Location vs Expression: Pointing at the Offending Element

OperationOutcome carries two closely related fields that both do the same job: location and expression. Both are pointers into the resource under evaluation, saying "here is the offending element." One is older and being deprecated; the other is the current preferred form. Knowing which is which — and knowing how to parse each — is what makes an OperationOutcome consumer useful. The site's OperationOutcome reader resolves both against a paste-in resource. For the wider FHIR framing, our FHIR coverage for clinical teams has more.

The Two Fields

  • location — a legacy array of dot-path strings pointing at the element
  • expression — an array of FHIRPath expressions pointing at the element

Both live on the same issue entry. Both are arrays because one issue can point at multiple locations — a duplicate detected across two entries in a Bundle, for instance. Consumers should read both; older servers only produce location, newer ones prefer expression.

What `location` Looks Like

A location string uses XPath-flavored syntax with array indexes:

`` "location": ["Patient.name[0].family"] ``

or

`` "location": ["/f:Patient/f:name[1]/f:family"] ``

Two flavors are in the wild — dot-path and XPath. Callers have to handle both, and the mixing is one of the reasons location is deprecated.

What `expression` Looks Like

expression uses FHIRPath, the same language the invariants use:

`` "expression": ["Patient.name[0].family"] ``

Cleaner, one flavor, and it can be evaluated against the resource to jump directly to the offending element. The OperationOutcome reader evaluates expression when you paste both an outcome and a sample resource.

Which To Emit

  • Emit expression on new servers
  • Continue to emit location for compatibility if consumers depend on it
  • Prefer FHIRPath dot-path form when emitting location, since it is closer to expression and easier to migrate

For custom validators, the emit-both pattern is safest. For the design side, designing your own OperationOutcome for a custom validator covers the shape.

Which To Consume

Consume expression first if present, location as fallback. A well-written OperationOutcome consumer normalizes both into an internal representation and lets the rest of the code depend on it.

Callers that only consume location miss issues from newer servers that emit expression only. Callers that only consume expression miss issues from older servers.

Multiple Pointers Per Issue

An issue can point at multiple elements. A referential-integrity error might point at both the referrer and the target. A cross-field validation might point at both fields involved. Both location and expression are arrays for this reason.

Callers that read only the first element lose context. Handle the array, not just the first entry.

Resolving Pointers Against The Resource

An expression pointer resolves against the resource that was being evaluated. The consumer needs both the outcome and the resource to render "here is what's wrong" usefully. Without the resource, the pointer is a string in space.

The reader takes both as input for exactly this reason: paste the outcome, paste the resource, get an annotated view.

What Happens On A Bundle

For OperationOutcome from a batch or transaction Bundle, the expression pointers usually refer to entries within the Bundle: Bundle.entry[3].resource.name[0].family. That is deep, and callers that flatten to just the resource lose the entry context. Preserve the full path.

For the code-vocabulary side of the same triage, issue.code vocabulary and what it actually means covers the reasons.

The Short Version

expression is the current form; location is legacy. Consumers handle both. Pointers are arrays, not single values. Resolve against the original resource to render usefully. For the base pattern, reading an OperationOutcome for the first time is the entry.

Dataviz-particles diagram of location vs expression pointers side by side, both resolving against a Bundle entry, with expression highlighted as the preferred form, on a light navy field with dataviz-blue accents

Sources