Skip to main content
Version: v0.0.13

Variable: WARNING_CODES

const WARNING_CODES: object

Stable string codes for every Tier-2 warning the record parser may emit. key === value so Object.values(...) yields a stable snapshot set.

Type Declaration

ASTM_NONSTANDARD_DELIMITERS

readonly ASTM_NONSTANDARD_DELIMITERS: "ASTM_NONSTANDARD_DELIMITERS" = "ASTM_NONSTANDARD_DELIMITERS"

The header declared delimiters other than the canonical H|\^&: tolerated, noted.

ASTM_RECORD_AMBIGUOUS_MESSAGE_KIND

readonly ASTM_RECORD_AMBIGUOUS_MESSAGE_KIND: "ASTM_RECORD_AMBIGUOUS_MESSAGE_KIND" = "ASTM_RECORD_AMBIGUOUS_MESSAGE_KIND"

A message carried both a Q (request) and an R (result) record: a contradictory shape. The message is classified host-query (the Q dominates, so it is never read as a result set) and this warning flags the anomaly. Positional context only; no field value.

ASTM_RECORD_AMBIGUOUS_VALUE_SPLIT

readonly ASTM_RECORD_AMBIGUOUS_VALUE_SPLIT: "ASTM_RECORD_AMBIGUOUS_VALUE_SPLIT" = "ASTM_RECORD_AMBIGUOUS_VALUE_SPLIT"

A result value field carried an unescaped component delimiter, so it split into more than one component. Both the full raw value and the split are surfaced and this warning fires: the ambiguity is never resolved silently into a truncated value.

ASTM_RECORD_DELIMITERS_REDECLARED

readonly ASTM_RECORD_DELIMITERS_REDECLARED: "ASTM_RECORD_DELIMITERS_REDECLARED" = "ASTM_RECORD_DELIMITERS_REDECLARED"

A later H (header) record declared a different delimiter set from the one in force, and the parser followed it: that header and every record after it are read with the newly-declared delimiters, until the next H. Records already read keep the set that was in force when they were read: a redeclaration never reinterprets bytes that have already been consumed.

A stream carrying several messages back to back is ordinary, and a header that simply repeats the delimiters already in force is a no-op that warns nothing. This code fires only when the set actually changes, because that is the point at which a reader still using the old set would begin merging fields together.

ASTM_RECORD_FIELDS_UNSEPARATED

readonly ASTM_RECORD_FIELDS_UNSEPARATED: "ASTM_RECORD_FIELDS_UNSEPARATED" = "ASTM_RECORD_FIELDS_UNSEPARATED"

The delimiters in force found no field separator at all in a record that carries content beyond its type letter, so the whole record read back as a single field and none of its modeled fields could be recovered. The raw line is surfaced intact and nothing is dropped, but on a result record it means the value, the units and the status are all absent from the parsed model.

This is one signature of a record being read with a delimiter set that does not belong to it, which is how a delimiter-scoping mistake turns into lost values. It is reported rather than repaired, because recovering the fields would mean guessing which set the sender meant.

Its absence is not evidence that a record was read in its own set. This tests one of the four delimiter roles, the field separator, and only in its total form, where that separator occurs in the line (unescaped). Two whole classes of the same loss are outside it: a foreign set whose field separator happens to occur somewhere in the line still splits (on the wrong boundaries, silently, and this can happen to one record inside a run of these warnings); and a set differing in the repeat, component or escape role usually splits into fields normally, where a mis-split component can cost a test identity while the value survives, and where an &X& sequence whose body is a delimiter is an opaque atom, so that delimiter does not split and every field after it shifts. The escape role's worst case has narrowed and not disappeared: an escape character heading no sequence is now read as a literal and reported under WARNING_CODES.ASTM_UNPAIRED_ESCAPE_CHARACTER rather than merging the rest of the record, but a delimiter swallowed inside an &X& body is reported only by WARNING_CODES.ASTM_UNKNOWN_ESCAPE_SEQUENCE, which is tolerable. Treat this code as a report that one record definitely lost its fields, never as a sweep that would have fired if any had.

ASTM_RECORD_ORPHAN_COMMENT

readonly ASTM_RECORD_ORPHAN_COMMENT: "ASTM_RECORD_ORPHAN_COMMENT" = "ASTM_RECORD_ORPHAN_COMMENT"

A C (comment) record had no valid preceding H/P/O/R parent: an orphan. The comment is attached to the message root (attachedToRoot: true) and surfaced, never dropped.

ASTM_RECORD_PARTIAL_TIMESTAMP

readonly ASTM_RECORD_PARTIAL_TIMESTAMP: "ASTM_RECORD_PARTIAL_TIMESTAMP" = "ASTM_RECORD_PARTIAL_TIMESTAMP"

A YYYYMMDDHHMMSS timestamp had an odd digit run that truncates a two-digit component in half (e.g. a partial day/hour). The raw run is preserved and the structured value stops at the last complete component: the dangling digit is never zero-filled into a fabricated time.

ASTM_RECORD_UNDEFINED_ABNORMAL_FLAG

readonly ASTM_RECORD_UNDEFINED_ABNORMAL_FLAG: "ASTM_RECORD_UNDEFINED_ABNORMAL_FLAG" = "ASTM_RECORD_UNDEFINED_ABNORMAL_FLAG"

A result's abnormal-flag field (R field 7) carried a letter outside HL7 Table 0078. The flag is surfaced as undefined: never dropped, and never coerced to normal (a clinical error).

ASTM_RECORD_UNDEFINED_RESULT_STATUS

readonly ASTM_RECORD_UNDEFINED_RESULT_STATUS: "ASTM_RECORD_UNDEFINED_RESULT_STATUS" = "ASTM_RECORD_UNDEFINED_RESULT_STATUS"

A result's status field (R field 9) carried a letter that is not a recognized status. It is surfaced as undefined and, like every non-F status, never reads as active-final.

ASTM_RECORD_UNINTERPRETED_QUERY_STATUS

readonly ASTM_RECORD_UNINTERPRETED_QUERY_STATUS: "ASTM_RECORD_UNINTERPRETED_QUERY_STATUS" = "ASTM_RECORD_UNINTERPRETED_QUERY_STATUS"

A Q (request-information) record carried a request-information status code (field 13). The code set is [OSS-derived / paywalled] with no publicly-groundable enumeration, so the parser interprets none of them: the status is surfaced verbatim and this value-free warning flags that it was passed through uninterpreted, never mapped to a guessed meaning.

ASTM_RECORD_UNITS_ABSENT

readonly ASTM_RECORD_UNITS_ABSENT: "ASTM_RECORD_UNITS_ABSENT" = "ASTM_RECORD_UNITS_ABSENT"

A result carried a numeric value but no units (R field 5 empty). Units are vendor free text (not UCUM); a missing unit is flagged here and never defaulted, guessed, or converted.

ASTM_RECORD_UNKNOWN_TYPE

readonly ASTM_RECORD_UNKNOWN_TYPE: "ASTM_RECORD_UNKNOWN_TYPE" = "ASTM_RECORD_UNKNOWN_TYPE"

A record's type letter is not one of the modeled types: surfaced as an unsupported record, never dropped. Treat it as a possible lost message boundary, because a header the reader did not recognize as one does not open a new message.

ASTM_RECORD_UNPARSEABLE_REFERENCE_RANGE

readonly ASTM_RECORD_UNPARSEABLE_REFERENCE_RANGE: "ASTM_RECORD_UNPARSEABLE_REFERENCE_RANGE" = "ASTM_RECORD_UNPARSEABLE_REFERENCE_RANGE"

A result's reference-range field (R field 6) did not match a recognized form (low-high, <high, >low). The text is surfaced verbatim as unparsed: a bound is never fabricated.

ASTM_RECORD_UNREADABLE_REDECLARATION

readonly ASTM_RECORD_UNREADABLE_REDECLARATION: "ASTM_RECORD_UNREADABLE_REDECLARATION" = "ASTM_RECORD_UNREADABLE_REDECLARATION"

A later H (header) record could not declare a usable delimiter set: it was too short, or the field separator it named also appeared among the other three, leaving the four roles indistinguishable. The delimiters already in force are kept and every record is still surfaced; a set is never guessed and no record is dropped.

The same condition on the first header is unrecoverable and remains the ASTM_RECORD_UNDECLARED_DELIMITERS fatal: there is no earlier set to fall back to.

ASTM_UNKNOWN_ESCAPE_SEQUENCE

readonly ASTM_UNKNOWN_ESCAPE_SEQUENCE: "ASTM_UNKNOWN_ESCAPE_SEQUENCE" = "ASTM_UNKNOWN_ESCAPE_SEQUENCE"

An escape sequence body was not one of &F&/&S&/&R&/&E&: preserved verbatim.

ASTM_UNPAIRED_ESCAPE_CHARACTER

readonly ASTM_UNPAIRED_ESCAPE_CHARACTER: "ASTM_UNPAIRED_ESCAPE_CHARACTER" = "ASTM_UNPAIRED_ESCAPE_CHARACTER"

An escape character appeared where no escape sequence starts (an escape sequence is the escape character, one body character, and the escape character again). It is read as the literal character it is and kept byte-for-byte in the decoded value. Nothing is dropped and no byte is invented: this flags that the sender did not write the character the spec-clean way, which is &E&.

What it replaced is the reason it exists. The codec used to read such a character as the opening of a sequence that never closed and merge the whole remainder of the record into the field it sat in, reporting nothing at all. One & in a result value cost the units, the abnormal flag and the status together and left the status reading unspecified rather than final; one in a surname cost the patient's birth date and sex. Emit then re-escaped the merged text into a spec-clean-looking line that read back as the same wrong value, so the mis-read survived a round trip without ever surfacing.

This code is not a statement about the rest of the record. It reports one character. A different escape character in the same record may still head a real three-character sequence, and if that sequence's body happens to be a delimiter (&|& under the canonical set) the atom rule means that delimiter does not split. That case is reported separately, under WARNING_CODES.ASTM_UNKNOWN_ESCAPE_SEQUENCE, and it can still cost a field boundary.

PROFILE_QUIRK_APPLIED

readonly PROFILE_QUIRK_APPLIED: "PROFILE_QUIRK_APPLIED" = "PROFILE_QUIRK_APPLIED"

The downgraded form an active vendor AstmProfile produces from a deviation it expects (see src/profiles/). The original warning is never dropped: its code moves to AstmRecordWarning.toleratedCode, the warning is re-badged PROFILE_QUIRK_APPLIED with expected: true and the tolerating profile named, so a consumer can filter known, grounded noise while the fact of the deviation, and where it was, survives. A profile can only ever reach this path for a non-safety-critical code (enforced at profile-definition time); a safety-critical deviation (a result value, flag, status, patient identifier, code system, or a frame-integrity warning) can never be tolerated, so it can never be re-badged here.

Example

import { parseAstmRecords, WARNING_CODES } from "@cosyte/astm";
const msg = parseAstmRecords("H|\\^&\rL|1\r");
msg.warnings.some((w) => w.code === WARNING_CODES.ASTM_RECORD_UNKNOWN_TYPE);