---
title: "I reported four missing standard fields. All four exist."
description: "No such column 'BillToContactId' on entity 'Order' is a sentence you believe. Under API 67.0 user mode it also fires for a field that exists and that your profile simply cannot see — and sf sobject describe hides both cases identically."
source: "https://noconaconsulting.com/blog/no-such-column-field-level-security/"
---

# I reported four missing standard fields. All four exist.

_Build log · Doorvana · Garage door manufacturing & service_

No such column 'BillToContactId' on entity 'Order' is a sentence you believe. Under API 67.0 user mode it also fires for a field that exists and that your profile simply cannot see — and sf sobject describe hides both cases identically.

Nocona Consulting · September 30, 2026 · 5 min read

Some errors you argue with. Some you believe immediately, write down, and build around.

```plaintext
No such column 'BillToContactId' on entity 'Order'
```

That is the second kind. It names the field, it names the object, and it says the thing does not exist. I read it, accepted it, wrote it up in the build notes as a gap in the standard `Order` object, and moved on to designing around the absence.

The field exists. So do three others I had written off the same way.

## Where it came from

The context was the Work Order to Order billing bridge at [Doorvana](https://noconaconsulting.com/work/) — a completed `WorkOrder` becoming a Draft `Order` on a single revenue ledger. Orders need a payer, and a payer is an Account and often a Contact, so `Order.BillToContactId` is the obvious place to put one.

Under **API version 67.0 Apex runs in user mode by default**. Queries and DML resolve against the running user’s field-level security rather than with full system access. So when the code referenced `BillToContactId`, the platform tried to resolve that field _as me_, could not, and said so in the only vocabulary it has for an unresolvable column.

## Two different facts, one error message

Here is the part worth internalising. Under user mode these two situations are indistinguishable from the error text:

-   The field does not exist on the object.
-   The field exists and the running user has no field-level security on it.

And the first tool anyone reaches for does not separate them either:

describe reflects access, not schema

```bash
sf sobject describe --sobject Order --target-org <alias> \
  | jq -r '.fields[].name' | grep -i billto
# (no output)
```

No output. Which reads as proof, and is not. `sf sobject describe` returns the fields **accessible to the running user**. A standard field with no field permission is not listed as restricted; it is not listed at all. Describe is answering “can I use this field”, which is a perfectly good question and not the one being asked.

Administrator instinct is what makes this land

A System Administrator is accustomed to seeing everything, so “I cannot see it” collapses into “it is not there” without passing through a conscious step. Field-level security is per field, and some standard fields ship with no field permission granted to any profile — including System Administrator.

## The query that settles it

`EntityParticle`, through the Tooling API, describes the **schema**. It does not care what the running user can access:

Tooling API — does this field exist at all?

```sql
SELECT QualifiedApiName, DataType, IsCreatable, IsUpdatable
FROM EntityParticle
WHERE EntityDefinition.QualifiedApiName = 'Order'
  AND QualifiedApiName LIKE '%Contact%'
```

Run with `sf data query --use-tooling-api`, that returns `BillToContactId`, with a data type, on an object I had just finished documenting as not having it.

The same check across the two objects turned up three more standard fields I had quietly treated as absent: `Order.OpportunityId`, `Order.QuoteId` and `OrderItem.QuoteLineItemId` — which is to say, the entire standard trail from a Quote to the Order it produced. I had been prepared to rebuild that with custom lookups.

Rule of thumb

`describe` answers “can I use this field”. `EntityParticle` answers “does this field exist”. When an error says a standard field is missing, ask the second question before believing the first. It is one query and it is authoritative, and the alternative is a custom field permanently shadowing a standard one nobody could see.

## The fields that genuinely are not there

The contrast matters, because the same build turned up a real absence and the difference in how it behaves is instructive.

`OrderItem` has no discount field. `QuoteLineItem` has one. `OpportunityLineItem` has one. `OrderItem` carries `UnitPrice`, `Quantity`, `ListPrice` and `TotalPrice`, and nothing that expresses “less ten percent”.

That is not a permissions problem and no Tooling query rescues it — `EntityParticle` agrees the field is absent. It is a modelling constraint, and it has a consequence. Take an invented line: one unit at a list price of 150, agreed at ten percent off. It has to arrive on the `Order` as a unit price of 135, because there is nowhere else for the discount to live — or the booked revenue drifts away from what the customer signed. The booking service divides the discounted line total by the quantity, and a test asserts the Order total equals the quote total.

A genuine absence forces a design decision. An invisible field produces a design decision that did not need to be made, against a constraint that was not real. The two are worth five minutes of telling apart.

## What I changed about how I work

The original write-up said `Order.BillToContactId` does not exist. That claim is wrong and the correction is the more useful record of the two, because the wrong version says something true about the tooling: this is what an error message can make a competent person believe on first reading.

The rule that came out of it is small:

-   An error about a missing field is a claim about resolution, not about schema. Under user mode, those stopped being the same claim.
-   Before building a custom field to replace a standard one, run one `EntityParticle` query.
-   If the field exists and you cannot see it, the work is a field permission on a permission set, not a custom field. Those two paths diverge permanently — the second one leaves a custom field shadowing a standard field forever, and every integration that reads the standard one gets nothing.

## Practical summary

-   `No such column 'X' on entity 'Y'` under API 67.0 user mode fires for both a nonexistent field and an inaccessible one.
-   `sf sobject describe` shows accessible fields only, so it confirms the wrong hypothesis silently.
-   `SELECT QualifiedApiName, DataType FROM EntityParticle WHERE EntityDefinition.QualifiedApiName = 'Order'` through the Tooling API is the schema-level answer.
-   `Order.BillToContactId`, `Order.OpportunityId`, `Order.QuoteId` and `OrderItem.QuoteLineItemId` all exist and commonly have no field-level security on any profile.
-   `OrderItem` genuinely has no discount field. Resolve discounts into the unit price before the line reaches the Order.

Four standard fields, written off on the strength of an error message that was telling the truth about something else entirely.

-   Apex
-   Field-level security
-   Tooling API
-   Order
-   Metadata
-   SFDX

Disclosure: Doorvana's owner is also a co-owner of Nocona Consulting. This is a real engagement between two separate companies, but not an arm's-length one — and not an independent reference. [More on the work page](https://noconaconsulting.com/work/).

## FAQ

### Does No such column on entity mean the Salesforce field does not exist?

Not necessarily. Under Apex user mode, which is the default from API version 67.0, a field the running user has no field-level security on is not resolvable, and the resulting error is the same one raised for a field that genuinely does not exist. The message is a statement about what this user can resolve, not about the org's schema. Confirm against the schema before concluding a standard field is absent.

### Why does sf sobject describe not show a standard field that exists?

Because describe returns the fields accessible to the running user, not the object's full field list. A standard field with no field-level security for that user's profile is omitted entirely rather than shown as inaccessible. That makes describe a poor tool for answering does this field exist, while being a perfectly good tool for answering can I use this field right now.

### How do you prove a Salesforce field exists regardless of field-level security?

Query EntityParticle through the Tooling API, filtered on EntityDefinition.QualifiedApiName for the object. EntityParticle describes the schema rather than the running user's access, so it lists fields that describe omits and reports their data type. A field that appears in EntityParticle and not in describe exists and is invisible to you, which is a permissions task rather than a modelling one.

### Does the System Administrator profile automatically have access to every standard field?

No. System Administrator carries broad object and system permissions, but field-level security is per field and some standard fields ship with no field permission granted to any profile, including that one. Order.BillToContactId, Order.OpportunityId, Order.QuoteId and OrderItem.QuoteLineItemId are examples. Administrators are used to being able to see everything, which is what makes this failure read as a missing field rather than as a permission.

### Does the Salesforce OrderItem object have a discount field?

No. OrderItem carries UnitPrice, Quantity, ListPrice and TotalPrice, with no discount or percentage field of its own, unlike QuoteLineItem and OpportunityLineItem. Code moving a discounted quote line onto an Order has to resolve the discount into the unit price — divide the discounted line total by the quantity — or the booked revenue on the Order will not match what the customer agreed to.
