Skip to content

Linting & validation

octofhir-sof has two offline checkers for ViewDefinitions:

  • validate — structural spec invariants only, no FHIR package or database. Covers FH06–FH10.
  • lint — schema-driven selector and generated-SQL checks against a FHIR package (--package), and/or the portable FHIRPath subset (--shareable). Covers FH01–FH05 (schema), FH06–FH10 (structure, also run by validate), and FH11 (shareable).

Both emit rustc-style diagnostics by default, or --json / --sarif (SARIF 2.1.0) for CI code scanning. Each FH* finding links to its rule reference page.

CodeSeverityWhat it flags
FH01errorUnknown FHIR element (with a did-you-mean suggestion)
FH02warningChoice element not narrowed with ofType()
FH03warningComplex element selected into a scalar column
FH04warningArray-valued element into a scalar column
FH05warningReference into a scalar without getReferenceKey()
FH06errorInvalid SQL name (column / constant / view name)
FH07errorMore than one of forEach / forEachOrNull / repeat
FH08errorDuplicate output column name
FH09errorunionAll branches with mismatched shape
FH10errorMissing resource, or a view that produces no columns
FH11error/warnFHIRPath outside the ShareableViewDefinition subset

FH01–FH05 need a schema (--package); FH06–FH10 are structural; FH11 is opt-in with --shareable.

Terminal window
octofhir-sof lint view.json --package hl7.fhir.r4.core
octofhir-sof lint view.json --package hl7.fhir.r5.core --version 5.0.0

--package enables the selector checks (FH01–FH05) by walking each FHIRPath selector against the real shape of the resource. With --version, the package is installed through the canonical manager if missing; without it, only an already-present package is used (offline). See FHIR versions.

The Shareable View Definition profile requires runners to implement only a minimal FHIRPath subset, so a view that stays inside it runs unchanged on any conformant engine. FH11 walks every FHIRPath expression in the view and flags anything outside that subset:

Terminal window
octofhir-sof lint view.json --shareable

This check needs no package — it is purely a FHIRPath analysis. The required subset allows the functions where, exists, empty, extension, ofType, first (plus the SQL-on-FHIR getResourceKey/getReferenceKey), the boolean operators and/or/not, math + - * /, the comparisons = != > <=, the indexer [], and String / Integer / Decimal / Boolean literals. The experimental join, lowBoundary, highBoundary warn; everything else is an error.

Exempt an engine-registered custom FHIRPath function so the strict pass does not hard-fail it (repeatable):

Terminal window
octofhir-sof lint view.json --shareable --allow-fn myCustomFn

You can combine --package and --shareable in one run.