Validation
BabelFHIR-TS generates runtime validators that evaluate FHIRPath constraints from StructureDefinitions. This page covers what the validators check, their limitations, and how they compare to external FHIR validators.
What Validators Check
The generated validate() methods DO check:
- FHIRPath constraints from StructureDefinition invariants
- Cardinality rules (min/max occurrences)
- Required fields from profiles
- Pattern constraints (
patternCodeableConcept,patternCoding) - Fixed values (top-level scalar fields,
meta.profile) - Prohibited fields (
max=0) - Slice validation for extension URL, pattern/value, and exists-extension discriminators
- Required ValueSet bindings (inline code validation when ValueSet is resolved)
- Bundle reference resolution (checks that bundled/contained references resolve)
- Extension structural rules (
ext-1,urlrequired, empty object check) - Data type correctness (string, number, boolean, etc.)
What Validators Don't Check
The generated validators DO NOT check:
- Terminology validation for non-required bindings or large ValueSets without
--tx-server - Cross-resource reference resolution (checking that references to external resources exist)
- Complex discriminator types (type, position) — only pattern/value, extension URL, and exists-extension discriminators supported
- Cross-resource business rules — application-specific logic
TIP
For comprehensive conformance testing, use the official HL7 FHIR Validator.
Runtime Validator Options
Every generated validate() function accepts an optional ValidatorOptions object as a second parameter. This enables runtime terminology validation, reference resolution, and debugging:
import { validateUSCorePatient } from "hl7.fhir.us.core-generated/USCorePatientValidator";
const result = await validateUSCorePatient(myPatient, {
terminologyUrl: "https://tx.fhir.org/r4",
fhirServerUrl: "https://hapi.fhir.org/baseR4",
httpHeaders: {
"https://tx.fhir.org/r4": "Bearer my-token",
},
traceFn: (value, label) => console.log(`[trace] ${label}:`, value),
});Available Options
| Option | Type | Description |
|---|---|---|
terminologyUrl | string | Terminology server URL for memberOf() evaluation. When set, validators make HTTP calls to $validate-code for ValueSet bindings that couldn't be resolved at generation time. |
fhirServerUrl | string | FHIR server URL for resolve() evaluation. When set, validators resolve external references by fetching from this server. |
httpHeaders | Record<string, string> | HTTP headers keyed by server URL. Use for authentication with terminology or FHIR servers. |
signal | AbortSignal | Cancels long-running async evaluations (e.g., terminology lookups). |
traceFn | (value: any, label: string) => void | Debug callback invoked for every FHIRPath trace() call. Useful for diagnosing constraint evaluation. |
INFO
Without terminologyUrl, validators skip memberOf() checks and report no errors for unresolvable ValueSet bindings. Without fhirServerUrl, resolve() expressions are not evaluated.
Continuous Validation Pipeline
Every pull request runs two independent CI pipelines that validate generated code against real-world FHIR Implementation Guides. For each IG, the pipeline:
- Downloads the FHIR package from a registry
- Generates TypeScript interfaces, validators, and classes
- Compiles the output with
tsc(zero errors required) - Generates
empty()andrandom()test resources for every profile - Validates those resources against two external FHIR validators
Tested Implementation Guides (30 packages)
| Category | Implementation Guide | Package | FHIR |
|---|---|---|---|
| US | US Core | hl7.fhir.us.core@8.0.0 | R4 |
| US | QI-Core | hl7.fhir.us.qicore@6.0.0 | R4 |
| US | mCODE | hl7.fhir.us.mcode@4.0.0 | R4 |
| US | SDOH Clinical Care | hl7.fhir.us.sdoh-clinicalcare@2.2.0 | R4 |
| US | NDH (National Directory) | hl7.fhir.us.ndh@1.0.0 | R4 |
| US | CARIN BB | hl7.fhir.us.carin-bb@2.1.0 | R4 |
| US | CQF Measures | hl7.fhir.us.cqfmeasures@4.0.0 | R4 |
| US | Physical Activity | hl7.fhir.us.physical-activity@1.0.0 | R4 |
| DaVinci | PAS | hl7.fhir.us.davinci-pas@2.0.1 | R4 |
| DaVinci | CDex | hl7.fhir.us.davinci-cdex@2.1.0 | R4 |
| DaVinci | PDex | hl7.fhir.us.davinci-pdex@2.1.0 | R4 |
| DaVinci | DTR | hl7.fhir.us.davinci-dtr@2.1.0 | R4 |
| DaVinci | Alerts | hl7.fhir.us.davinci-alerts@1.0.0 | R4 |
| DaVinci | DEQM | hl7.fhir.us.davinci-deqm@4.0.0 | R4 |
| DaVinci | Drug Formulary | hl7.fhir.us.davinci-drug-formulary@2.1.0 | R4 |
| Universal | IPS | hl7.fhir.uv.ips@2.0.0 | R4 |
| Universal | SMART App Launch | hl7.fhir.uv.smart-app-launch@2.2.0 | R4 |
| Universal | SDC (Structured Data Capture) | hl7.fhir.uv.sdc@3.0.0 | R4 |
| Universal | Genomics Reporting | hl7.fhir.uv.genomics-reporting@3.0.0 | R4 |
| Universal | CPG (Clinical Practice Guidelines) | hl7.fhir.uv.cpg@2.0.0 | R4 |
| DE | ISiK Basis | de.gematik.isik-basismodul@4.0.3 | R4 |
| DE | ISiK Medikation | de.gematik.isik-medikation@4.0.1 | R4 |
| DE | KBV eRezept | kbv.ita.erp@1.1.1 | R4 |
| DE | DE Basisprofil | de.basisprofil.r4@1.5.0 | R4 |
| CH | CH Core (Switzerland) | ch.fhir.ig.ch-core@5.0.0 | R4 |
| AU | AU Core (Australia) | hl7.fhir.au.core@1.0.0 | R4 |
| IHE | PIXm | ihe.iti.pixm@3.0.4 | R4 |
| IHE | MHD | ihe.iti.mhd@4.2.2 | R4 |
| R5 | AE Research (R5) | hl7.fhir.uv.ae-research-ig@1.0.1 | R5 |
| R5 | eMedicinal Product (R5) | hl7.fhir.uv.emedicinal-product-info@1.0.0 | R5 |
Firely .NET SDK Validator
The first pipeline validates generated resources using the Firely .NET SDK validator (Firely.Fhir.Validation.R4 v3.1.1).
Known Firely SDK Issues
23 profiles are excluded from Firely validation due to schema loading or parser bugs in the Firely SDK. See Firely SDK Exclusions below.
HL7 Java Validator
The second pipeline validates using the official HL7 FHIR Validator (v6.9.4), the reference implementation for FHIR conformance checking.
Known HL7 Validator Issues
37 profiles are excluded from HL7 validation due to terminology server limitations, profile resolution failures, missing snapshots, or cross-profile validation issues. See HL7 Java Validator Exclusions below.
INFO
Terminology validation requires a tx server. The pipeline uses --tx-server https://tx.fhir.org/r4 during generation to expand ValueSets and produce valid codes.
Firely SDK Exclusions
23 profiles are excluded from Firely validation statistics because they fail due to bugs in the Firely .NET SDK's profile/schema loading or parser, not issues with generated code.
Discriminator Loading Failures
The Firely SDK cannot evaluate complex discriminator expressions in certain StructureDefinitions (fixed[x]/pattern[x]/resolve() errors). 15 profiles across 4 IGs:
| Package | Profiles | Error Pattern |
|---|---|---|
| ISiK Basis | ISiKOrganisation, ISiKOrganisationFachabteilung, ISiKAngehoeriger, ISiKPersonImGesundheitsberuf, ISiKPatient | discriminator should have a 'fixed[x]', 'pattern[x]' or binding element |
| IPS | CompositionUvIps, DiagnosticReportUvIps, BundleUvIps | discriminator path 'resolve()' — FHIR R4 spec explicitly supports this |
| CH Core | CHCorePractitioner, CHCorePractitionerEPR, CHCorePatient, CHCorePatientEPR | Failed to load 'ch-core-address' — compound discriminator on Extension |
| DaVinci PAS | PASClaimBase, PASClaim, PASClaimUpdate, PASClaimInquiry, PASRequestBundle, PASInquiryRequestBundle | Failed to load — discriminator evaluation failure |
Parser Ordering Bug
The Firely SDK reports false element ordering errors (coding vs text) when parsing against certain profiles. The same resources validate without errors against base FHIR resource types. 5 profiles:
| Package | Profiles |
|---|---|
| ISiK Basis | ISiKDiagnose, ISiKProzedur |
| DaVinci PAS | PASEncounter, PASDeviceRequest, PASTask |
TIP
Both validators exclude profiles independently. Some profiles (e.g. ISiKOrganisation, ISiKPatient) are excluded from both pipelines for different reasons.
HL7 Java Validator Exclusions
37 profiles are excluded from HL7 validation statistics due to terminology server limitations, profile resolution failures, missing snapshots, cross-profile validation, or discriminator evaluation failures.
Profile Resolution Failures
The HL7 validator cannot resolve profile references needed for slicing evaluation. 7 profiles in ISiK Basis:
| Profile | Error Pattern |
|---|---|
| ISiKOrganisation, ISiKOrganisationFachabteilung | Unable to resolve profile (identifier-bsnr) |
| ISiKAllergieUnvertraeglichkeit | Unable to resolve profile (CodingASK) |
| ISiKPersonImGesundheitsberuf | Unable to resolve profile (identifier-efn) |
| ISiKAbrechnungsfall | Unable to resolve profile (identifier-abrechnungsnummer) |
| ISiKPatient | Unable to resolve profile (identifier-kvid-10) |
| ISiKProzedur | Unable to resolve profile (CodingOPS) |
Missing Snapshots
The HL7 validator reports that certain StructureDefinitions have no snapshot, preventing validation. 3 profiles in ISiK Basis:
| Profile | Error Pattern |
|---|---|
| ISiKDiagnose, ISiKVersicherungsverhaeltnisSelbstzahler, ISiKVersicherungsverhaeltnisGesetzlich | has no snapshot - validation is ... |
Slicing Evaluation Failure
The HL7 validator cannot match discriminators for $this-based slicing. 1 profile:
| Profile | Error Pattern |
|---|---|
| ISiKAngehoeriger | Could not match any discriminators ($this) for slice RelatedPerson.name:Name |
Environment Errors
The HL7 validator reported internal errors unrelated to the generated resource content. 6 profiles:
| Package | Profiles |
|---|---|
| ISiK Basis | ISiKBerichtBundle, ISiKPatientMergeSubscription, ISiKLebensZustand, ISiKCodeSystem |
| IPS | BundleUvIps |
| DaVinci PAS | PASTask |
