> For the complete documentation index, see [llms.txt](https://php-fhir-tools.ardenexal.net/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://php-fhir-tools.ardenexal.net/validation/invariants.md).

# FHIRPath Invariant Validation

An *invariant* is a rule a FHIR resource must satisfy, written as a FHIRPath expression and identified by a `key` such as `obs-7`. This validator evaluates those expressions via `FHIRPathInvariantValidator` (backed by the [FHIRPath](/fhirpath/overview.md) engine). Each invariant is emitted as a `#[FHIRPathInvariant]` attribute carrying the invariant `key` (e.g. `obs-7`), `expression`, `human` message, and `severity`.

## How it works

The validator runs the invariant's `expression` through `FHIRPathService::evaluate()` against the validated value. The invariant **passes only when the result is the single boolean `true`**. Anything else is treated as a failure.

On failure, the violation severity is derived from the constraint's `severity`:

* `severity === 'warning'` → `fhir:warning` (maps to `warning`)
* otherwise → `fhir:error` (maps to `error`)

The violation message defaults to the invariant's `human` text, overridable via the `FHIRPathInvariant` key in `FHIRValidationMessageRegistry`. Null values are skipped (the invariant does not fire on an absent element).

The resolved `invariantKey` is preserved on the report as `FHIRValidationViolation::$invariantKey`, so consumers can correlate a violation back to its source invariant.

## Engine limitations are not conformance failures

If the FHIRPath engine cannot evaluate an expression (for example, an unsupported function), the validator catches the `FHIRPathException` and emits an INFO violation with the code `fhir:eval-error` instead of an ERROR:

```
FHIRPath invariant `obs-7` could not be evaluated: <expression>
```

Per the FHIR conformance specification, a tooling limitation must not be asserted as instance non-conformance, so these surface at `info` severity and never affect `isValid()`. Only FHIRPath engine exceptions are downgraded this way — any other throwable (a genuine bug) propagates rather than being masked.

{% hint style="info" %}
A valid resource will never receive a false-positive ERROR from an unsupported FHIRPath expression. If your engine covers all invariant expressions in your StructureDefinitions, no `fhir:eval-error` INFO violations appear.
{% endhint %}

See [Validation Reports & Violation Codes](/validation/reports.md) for how `fhir:eval-error` maps to severity.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://php-fhir-tools.ardenexal.net/validation/invariants.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
