Skip to main content
Version: v0.0.6

Troubleshooting

Common symptoms when integrating @cosyte/astm, and how to read what the parser is telling you.

The parse "succeeded" but the result looks wrong

@cosyte/astm is lenient: it recovers from vendor quirks rather than throwing. That means a surprising result usually comes with an explanation in warnings. Inspect them first:

const { warnings } = parseAstmRecords(raw);

for (const w of warnings) {
console.warn(w.code, w.message, w.position);
}

Each warning carries a stable code (WARNING_CODES) and positional context. If a deviation should be a hard failure for your integration, re-parse with { strict: true } to have it thrown instead.

A parse threw

Only Tier-3 fatal conditions (FATAL_CODES) throw in lenient mode: these mark input the parser cannot recover into a structured result. In { strict: true } mode, any tolerated deviation throws too. Catch and inspect the error's code to tell the two apart.

An accessor threw AstmAmbiguousStreamError

The parse succeeded; an accessor refused to answer. patient(), results(), orders(), comments() and query() read the whole stream, so they cannot answer for a stream that does not determine one answer, and refusing is the point: the alternative is one patient's results attributed to another. Two codes:

  • ASTM_AMBIGUOUS_MULTI_MESSAGE: the stream carries more than one HL message. Read each message's own records instead:

    for (const m of messages(msg)) {
    m.patient;
    m.results;
    }
  • ASTM_AMBIGUOUS_MULTI_PATIENT (from patient() only): one message carries several P records, so "the patient" is not determined. Read messages(msg)[n].patients for all of them.

The error carries code, a value-free position pointing at where the ambiguity became visible, and messageCount / patientCount. It never carries an identifier or a value, so it is safe to log. commentsFor() never throws this: the parent record you hand it already names the message.

Warning messages and logs

Warning message fields are safe to log: they never contain PHI. Never log the raw payload itself; it may carry protected health information.

A value came back without units, or a flag as "undefined"

That is the fail-safe design, not a bug. A numeric result with no units raises ASTM_RECORD_UNITS_ABSENT and the unit is left empty: never defaulted or guessed. An abnormal flag the parser does not recognize is surfaced as "undefined", never coerced to "normal". An unparseable reference range is surfaced verbatim with no invented bound. In every case the library refuses to hand you a confident wrong value: inspect the warning and decide.

A framed stream lost a frame, or a checksum is wrong

The frame layer validates every modulo-256 checksum and tracks the frame-number sequence. A bad-checksum frame is flagged trusted: false and never merged into a record (a warning in lenient mode, a thrown AstmFrameStrictError in strict); a sequence gap is warned and never silently bridged. Read frameWarnings from parseFramedAstm: each carries a frame number and byte offset, never the record bytes.

Known limitations

@cosyte/astm is feature-complete across both layers, but its promise is deliberately narrow. See What it does, and does not do for the full, honest boundary: no live I/O, units are verbatim free text (not UCUM), no bundled terminology dictionary (LIVD is bring-your-own), and M/S records are surfaced verbatim, never interpreted.

The API Reference always reflects exactly what this release ships: treat it as the source of truth over any prose above.