Skip to content

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, url required, 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:

ts
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

OptionTypeDescription
terminologyUrlstringTerminology 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.
fhirServerUrlstringFHIR server URL for resolve() evaluation. When set, validators resolve external references by fetching from this server.
httpHeadersRecord<string, string>HTTP headers keyed by server URL. Use for authentication with terminology or FHIR servers.
signalAbortSignalCancels long-running async evaluations (e.g., terminology lookups).
traceFn(value: any, label: string) => voidDebug 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:

  1. Downloads the FHIR package from a registry
  2. Generates TypeScript interfaces, validators, and classes
  3. Compiles the output with tsc (zero errors required)
  4. Generates empty() and random() test resources for every profile
  5. Validates those resources against two external FHIR validators

Tested Implementation Guides (30 packages)

CategoryImplementation GuidePackageFHIR
USUS Corehl7.fhir.us.core@8.0.0R4
USQI-Corehl7.fhir.us.qicore@6.0.0R4
USmCODEhl7.fhir.us.mcode@4.0.0R4
USSDOH Clinical Carehl7.fhir.us.sdoh-clinicalcare@2.2.0R4
USNDH (National Directory)hl7.fhir.us.ndh@1.0.0R4
USCARIN BBhl7.fhir.us.carin-bb@2.1.0R4
USCQF Measureshl7.fhir.us.cqfmeasures@4.0.0R4
USPhysical Activityhl7.fhir.us.physical-activity@1.0.0R4
DaVinciPAShl7.fhir.us.davinci-pas@2.0.1R4
DaVinciCDexhl7.fhir.us.davinci-cdex@2.1.0R4
DaVinciPDexhl7.fhir.us.davinci-pdex@2.1.0R4
DaVinciDTRhl7.fhir.us.davinci-dtr@2.1.0R4
DaVinciAlertshl7.fhir.us.davinci-alerts@1.0.0R4
DaVinciDEQMhl7.fhir.us.davinci-deqm@4.0.0R4
DaVinciDrug Formularyhl7.fhir.us.davinci-drug-formulary@2.1.0R4
UniversalIPShl7.fhir.uv.ips@2.0.0R4
UniversalSMART App Launchhl7.fhir.uv.smart-app-launch@2.2.0R4
UniversalSDC (Structured Data Capture)hl7.fhir.uv.sdc@3.0.0R4
UniversalGenomics Reportinghl7.fhir.uv.genomics-reporting@3.0.0R4
UniversalCPG (Clinical Practice Guidelines)hl7.fhir.uv.cpg@2.0.0R4
DEISiK Basisde.gematik.isik-basismodul@4.0.3R4
DEISiK Medikationde.gematik.isik-medikation@4.0.1R4
DEKBV eRezeptkbv.ita.erp@1.1.1R4
DEDE Basisprofilde.basisprofil.r4@1.5.0R4
CHCH Core (Switzerland)ch.fhir.ig.ch-core@5.0.0R4
AUAU Core (Australia)hl7.fhir.au.core@1.0.0R4
IHEPIXmihe.iti.pixm@3.0.4R4
IHEMHDihe.iti.mhd@4.2.2R4
R5AE Research (R5)hl7.fhir.uv.ae-research-ig@1.0.1R5
R5eMedicinal Product (R5)hl7.fhir.uv.emedicinal-product-info@1.0.0R5

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.

📊 Full Parity Report

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:

PackageProfilesError Pattern
ISiK BasisISiKOrganisation, ISiKOrganisationFachabteilung, ISiKAngehoeriger, ISiKPersonImGesundheitsberuf, ISiKPatientdiscriminator should have a 'fixed[x]', 'pattern[x]' or binding element
IPSCompositionUvIps, DiagnosticReportUvIps, BundleUvIpsdiscriminator path 'resolve()' — FHIR R4 spec explicitly supports this
CH CoreCHCorePractitioner, CHCorePractitionerEPR, CHCorePatient, CHCorePatientEPRFailed to load 'ch-core-address' — compound discriminator on Extension
DaVinci PASPASClaimBase, PASClaim, PASClaimUpdate, PASClaimInquiry, PASRequestBundle, PASInquiryRequestBundleFailed 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:

PackageProfiles
ISiK BasisISiKDiagnose, ISiKProzedur
DaVinci PASPASEncounter, 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:

ProfileError Pattern
ISiKOrganisation, ISiKOrganisationFachabteilungUnable to resolve profile (identifier-bsnr)
ISiKAllergieUnvertraeglichkeitUnable to resolve profile (CodingASK)
ISiKPersonImGesundheitsberufUnable to resolve profile (identifier-efn)
ISiKAbrechnungsfallUnable to resolve profile (identifier-abrechnungsnummer)
ISiKPatientUnable to resolve profile (identifier-kvid-10)
ISiKProzedurUnable to resolve profile (CodingOPS)

Missing Snapshots

The HL7 validator reports that certain StructureDefinitions have no snapshot, preventing validation. 3 profiles in ISiK Basis:

ProfileError Pattern
ISiKDiagnose, ISiKVersicherungsverhaeltnisSelbstzahler, ISiKVersicherungsverhaeltnisGesetzlichhas no snapshot - validation is ...

Slicing Evaluation Failure

The HL7 validator cannot match discriminators for $this-based slicing. 1 profile:

ProfileError Pattern
ISiKAngehoerigerCould 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:

PackageProfiles
ISiK BasisISiKBerichtBundle, ISiKPatientMergeSubscription, ISiKLebensZustand, ISiKCodeSystem
IPSBundleUvIps
DaVinci PASPASTask

Released under the ISC License.