Skip to main content
Version: v0.0.5

Troubleshooting

Common symptoms when converting v2 → FHIR, and how to read what the transform is telling you.

A converter returned value: undefined

Nothing could be safely emitted. This is by design, not an error - it happens for an empty input composite, an unparseable timestamp, or a numeric value that wasn't numeric. Check issues for the typed reason (e.g. TRANSFORM_TIMESTAMP_INVALID).

A field I expected is missing from the output

A missing FHIR element usually comes with a diagnostic explaining the refusal:

  • Identifier.system is absentTRANSFORM_IDENTIFIER_SYSTEM_UNRESOLVED: the assigning authority wasn't resolvable. Seed it via createNamingSystem({ authorities: { … } }). The value is never attached to a guessed system.
  • Coding.system is absentTRANSFORM_CODE_SYSTEM_UNRESOLVED (unknown mnemonic) or TRANSFORM_CODE_UNMAPPED (no coding system at all). The code is preserved verbatim, never invented.
  • HumanName.use / Address.use is absent → the v2 code has no equivalent in the IG's table map (TRANSFORM_NAME_USE_UNMAPPED / TRANSFORM_ADDRESS_USE_UNMAPPED). It is surfaced, never guessed.

My timestamp lost its time-of-day

TRANSFORM_TIMESTAMP_NO_TIMEZONE: the v2 timestamp had a time but no offset, and FHIR forbids a time without a zone - so it was reduced to date precision rather than assuming UTC (which would shift the clinical instant by hours). Supply assumeTimezoneOffsetMinutes if you know the sender's offset.

My unit didn't populate Quantity.code

TRANSFORM_UNIT_NOT_UCUM: the unit wasn't declared UCUM or failed the UCUM shape check, so it was preserved verbatim in Quantity.unit with code/system absent. Magnitudes are never converted (mg/dL ↔ mmol/L is analyte-dependent and unsafe to automate).

Are diagnostics safe to log?

Yes. A TransformIssue carries only a stable code, a severity, a positional v2 location, and a FHIR path - never a value. Its message is static. Do not log the raw v2 message or the produced resource values; those carry PHI.

Known limitations

  • Message families: the IG-covered set - toFhir(msg) assembles ADT → Patient + Encounter, ORU^R01 → DiagnosticReport + Observation, ORM_O01 / OML_O21 → ServiceRequest and RXO → MedicationRequest, and the thin IG singles VXU_V04 → Immunization, SIU_S12 → Appointment, and MDM_T02 → DocumentReference. The v2→FHIR direction is feature-complete for the IG-covered message set; terminology depth, profiles, and the reverse FHIR → v2 direction are not implemented.
  • Thin-IG-single scope - each family covers the single trigger the IG maps and the resource-internal fields; references to resources this tier does not yet build (Immunization performer/manufacturer/location, Appointment practitioner/location participants, DocumentReference author/authenticator) are deferred and flagged, never dangling. Immunization.status follows the IG's three conditioned rows (RXA-21 = Dentered-in-error, unvalued RXA-20 → completed, else the HL70322 map); a required status the IG cannot ground withholds the resource (a valued-but-unmapped RXA-20, an IG-unmatched SCH-25, or a non-AV TXA-19). The Appointment patient participant's IG-unsourced required status is a data-absent-reason primitive, and the MDM document body is base64-encoded verbatim (the IG-assigned application/text / text/hl7v2 contentType), carried and never interpreted.
  • ORU scope - DiagnosticReport.category is not defaulted (the IG segment map sets none; it is realm-dependent), the results graph uses the first PID/PV1 (multiple patient result groups are not handled), and OBR performers/specimen and basedOn ServiceRequest are deferred. An OBX value type with no first-class FHIR value[x] (NA, ED, DR, TM, NR, …) preserves the raw value as valueString and flags it - never a fabricated typed value.
  • Terminology value translation - coded fields with an IG mappedVia value ConceptMap are value-translated via toFhirCodeableConceptVia: RXR route/site (HL70162/HL70550), SCH-8 appointment type (HL70277), RXO-9 substitution (HL70161), and OBR-5 priority (HL70485). Each map is transcribed and verified firsthand against the raw published IG ConceptMap JSON; a source code the IG leaves in its (unmapped) group is flagged (TRANSFORM_CODE_UNMAPPED), never coerced. Two fields the IG maps into SNOMED CT (RXR-4 method, SCH-7 reason) stay structural (SNOMED is not bundled - BYO ConceptMap), and fields the IG ships no value map for (TXA-2 document type, RXA-5 vaccine code) are carried as-is. The built-in NamingSystem code-system seed is still the FHIR-core-fixed systems; the full HL7 THO crosswalk beyond these maps is not implemented.
  • No terminology content, no unit conversion, R4-only.