Skip to main content
Version: v0.0.2

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 absent → TRANSFORM_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 absent → TRANSFORM_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 = D → entered-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.