Skip to main content
Version: v0.0.3

Troubleshooting

@cosyte/hl7 follows Postel's Law: the parser is liberal (tolerate and warn), the serializer is conservative (always spec-clean). Most surprises come from that split. This page covers the common ones, then the Known Limitations you should design around.

"I got warnings, not an error"

That's the default and it's intentional. A vendor quirk becomes a tolerance warning on msg.warnings. The parse still succeeds. Each warning carries a stable code you can branch on:

import { parseHL7 } from "@cosyte/hl7";

// A ZZZ segment isn't a known HL7 segment: tolerated, surfaced as a warning.
const raw = "MSH|^~\\&|A|B|C|D|20260101||ADT^A01|1|P|2.5\rZZZ|1";

const msg = parseHL7(raw);

msg.warnings.some((w) => w.code === "UNKNOWN_SEGMENT"); // => true

The 19 warning codes are a public, versioned contract. They won't be renamed under you without a breaking change. See Core Concepts for what each one means.

"I want failures, not warnings"

Pass { strict: true }. Strict mode promotes every Tier-2 tolerance warning to a thrown Hl7ParseError, so nothing quirky slips through silently:

import { parseHL7 } from "@cosyte/hl7";

const raw = "MSH|^~\\&|A|B|C|D|20260101||ADT^A01|1|P|2.5\rZZZ|1";

// The same input that warned above now throws under strict.
parseHL7(raw, { strict: true });

"It threw even though I didn't ask for strict"

Four fatal structural codes throw regardless of mode. They mean the input isn't recoverable as HL7 at all: NO_MSH_SEGMENT, MSH_TOO_SHORT, INVALID_ENCODING_CHARACTERS, and EMPTY_INPUT.

import { parseHL7 } from "@cosyte/hl7";

// No MSH, no message: fatal even in the default lenient mode.
parseHL7("");

Catch Hl7ParseError and read its code to distinguish them. Everything else is a warning.

"Non-ASCII text comes out garbled"

Character set is declared in MSH-18 (HL7 Table 0211). The parser resolves it and decodes accordingly; resolveCharset / canonicalCharset let you inspect how a given code is treated (decoded vs. preserved) before you rely on it.

"A batch/file won't parse"

parseHL7 parses one message. For an FHS/BHS-led batch or file envelope, use splitBatch, which demarcates the individual MSH-led messages, parses each independently (a malformed message is isolated, never dropping its siblings), and reconciles the declared BTS-1/FTS-1 counts:

import { splitBatch } from "@cosyte/hl7";

const result = splitBatch(rawBatch);
for (const entry of result.messages) {
// each entry is an ok/failure record: a bad message never suppresses the rest
}

Known limitations

Design around these. They're deliberate scope choices, not bugs:

  • Vendor profiles are structural and evidence-grounded. Built-ins ship for Epic, Cerner, Meditech, Athena, a generic lab, and the Visage 7 and Philips Vue PACS imaging systems. A vendor "quirk" is encoded only when a real document grounds it: a publicly published vendor interface spec (as with Visage 7 and Philips Vue PACS) or a real de-identified feed, never invented, so broader per-vendor coverage expands as grounded sources arrive rather than shipping speculative rules.
  • No terminology validation, no network, no bundled codesets. codingSystem() reports what a code claims (HL7 Table 0396). It does not validate a value against LOINC, SNOMED CT, RxNorm, or any external system, and nothing here makes a network call.
  • One ACK acknowledges one message. Batch-level ACK reconciliation is out of scope; for MLLP transport framing and ACK correlation over the wire, use the sibling package @cosyte/mllp.
  • Datetimes are fidelity values, not eager Dates. TS fields preserve the raw string and a precision so timezone and precision are never silently lost; convert to a Date explicitly when you need one.
  • Error snippets may carry field content (PHI) by design. Warning messages never echo a field's value (only positional context), but a fatal Hl7ParseError.snippet may include the offending bytes. That's the documented consumer-redaction boundary: redact snippet at your logging edge.
  • Pre-alpha (0.0.x), published on npm at 0.0.1. The 19 warning codes are a stable contract, but the broader surface may still evolve before a 1.0.

Still stuck?

Open an issue at github.com/cosyte/hl7/issues with a synthetic (never real-PHI) message that reproduces it.