Validation & issues API
Dictionary conformance as data: the validator, the FixIssue shape every analysis entry point returns, the stable issue-code catalogue, and the conditional-rule extension point. Generated from @boarteam/fix 0.5.2 as installed; the doc text is the library’s own. Guide: Validating FIX messages.
validatefunctionsince 0.1.0
function validate(message: ParsedMessage, dict: Dictionary | FixtDictionaries, options?: ValidateOptions): FixIssue[]Source: packages/fix/src/validate/validate.ts:140
Validate a parsed FIX message against a dictionary, returning diagnostics as data. Never throws — every conformance problem is a returned FixIssue.
The checks are the dictionary-conformance complement to parse, which owns wire decoding (framing, group reconstruction, numeric/Boolean coercion, group-count consistency). validate adds, over the structured message:
- presence — every required (
reqd: 'Y') field/group is present, gated by its ancestry: a required field inside an optional, absent component is not required; - enum membership — an enumerated field's value (each token, for multi-valued fields) is one of its dictionary values;
- value format — the verbatim datatypes the parser keeps as strings (dates, times,
month-year, currency, country) are well-formed, single-characterchars are one character, and numbers/Booleans are lexically valid; - empty values — a tag present with no value is rejected;
- conditional rules — the
data→Lengthcompanion (derived from the dictionary) plusDEFAULT_CONDITIONAL_RULESand any caller-supplied rules.
The value, enum, and empty checks run on every field in the parsed tree, so they work even when the MsgType is unknown (the structure is then flat); presence and conditional checks need the message definition and are skipped with a single validate/unknown-msgtype notice when it is missing.
validate is self-contained: it re-derives every conformance fact from the message and the dictionary, so it gives a complete verdict on a hand-built or post-parse-mutated ParsedMessage without needing the parse issues. As a result one class of problem — a number/Boolean field whose value is lexically invalid (44=abc) or empty (44=) — is reported by both passes under distinct codes (parse/invalid-float from decoding; validate/invalid-value or validate/empty-value from conformance). Everything else is disjoint: framing, group reconstruction, and group-count consistency are parse-only; presence, enum membership, conditional rules, and the formats the parser keeps verbatim are validate-only. Concatenate both lists for the full picture and dedupe by (refTagID, path) if the numeric double-report is unwanted.
dict may also be a FIXT transport/application pair (FixtDictionaries). The message is then validated against the pair's merged view AND every issue is attributed to a layer (FixIssue.layer): findings on a session (admin) message or on transport envelope fields are session (answer with a session Reject(3)), the rest are application (answer with a BusinessMessageReject(j)). Admin messages additionally get a session-layer purity check — an application-only field on a session message is flagged validate/field-outside-layer, mirroring how FIXT engines validate admin traffic against the transport dictionary alone. A resolveApp hook routes the app dictionary by the message's ApplVerID(1128), falling back to the pair's defaultApplVerID.
| Parameter | Type | Description |
|---|---|---|
| message | ParsedMessage | A ParsedMessage (typically from parse). |
| dict | Dictionary | FixtDictionaries | The dictionary to validate against. |
| options? | ValidateOptions | See ValidateOptions. |
Returns FixIssue[] — Every conformance finding, as data; empty when the message obeys the dictionary.
ValidateOptionsinterfacesince 0.1.0
interface ValidateOptionsSource: packages/fix/src/validate/validate.ts:24
Options for validate.
conditionalRules?: ConditionalRule[]Extra conditional-presence rules, evaluated after the built-ins. Use this to model the
C(required-by-prose) rules the engine does not ship — seeConditionalRule.useDefaultConditionalRules?: booleanWhether to run the built-in conditional rules (
DEFAULT_CONDITIONAL_RULES). Defaults totrue; setfalseto run only your ownValidateOptions.conditionalRules.
FixIssueinterfacesince 0.1.0
interface FixIssueSource: packages/fix/src/errors.ts:205
A single diagnostic, returned as data — never thrown — by every analysis entry point (parse, validate, validateDictionary). This is the demoted, structured successor to the legacy FixProtocolException: the same FIX session-reject context (refTagID/refSeqNum/refMsgType/sessionRejectReason) survives, but as fields on a value the caller inspects rather than a control-flow exception.
Issue codes are part of the package's public contract and follow SemVer: a stable, machine-readable identifier (see KnownIssueCode).
code: KnownIssueCode | stringStable, machine-readable identifier for the kind of problem (see
KnownIssueCode).The shipped type is
KnownIssueCode | (string & {})— the& {}intersection keeps editor autocompletion for the known codes while accepting any string. It is rendered here asKnownIssueCode | string, which is what it means.severity: FixSeverityHow serious the issue is.
message: stringHuman-readable explanation. Not stable across versions; do not match on it.
path?: stringDotted path to the offending location within the parsed structure, when applicable (e.g.
"NoMDEntries[2].MDEntryType"). Absent for whole-message issues.refTagID?: numberThe tag the issue concerns (FIX
RefTagID, tag 371).refSeqNum?: numberThe sequence number of the offending message (FIX
RefSeqNum, tag 45).refMsgType?: stringThe
MsgTypeof the offending message (FIXRefMsgType, tag 372).sessionRejectReason?: numberThe FIX
SessionRejectReason(tag 373) code, when the issue maps to one. Kept as a number to avoid coupling the engine to a particular dictionary's enum.layer?: FixLayerThe FIXT layer this issue belongs to. Set only when validating against a transport/application dictionary pair — see
FixLayer.
FixSeveritytypesince 0.1.0
Source: packages/fix/src/errors.ts:6
Severity of a FixIssue. error marks the message (or dictionary) invalid; warning flags something suspect that does not by itself make the input unusable; info is advisory (e.g. an unknown-but-tolerated tag).
errorwarninginfo
FixLayertypesince 0.4.0
Source: packages/fix/src/errors.ts:15
Which FIXT layer an issue belongs to, when validation ran against a transport/application dictionary pair: session findings are transport-owned (admin messages, envelope fields) and map to a session-level Reject(3); application findings map to a BusinessMessageReject(j). Absent when validating against a single dictionary, which has no layering to attribute.
sessionapplication
KnownIssueCodetypesince 0.1.0
Source: packages/fix/src/errors.ts:29
The catalogue of issue codes the engine currently emits. Codes are part of the public SemVer contract, so this union documents the known set and gives callers autocompletion and exhaustiveness — while FixIssue.code stays open (KnownIssueCode | string) so a custom dictionary or future milestone can introduce new codes without a type break. The dict/* family is raised by validateDictionary, the parse/* family by parse, the validate/* family (presence/enum/datatype/conditional) by validate, and the extend/* family by extendDictionary. For extend/* codes the severity encodes the outcome: error = the operation was skipped or reverted, warning = applied — or, for extend/duplicate-member, already satisfied (the redundant member was not added again) — but worth review, info = advisory.
dict/missing-versiondict/missing-begin-stringdict/missing-datatypesdict/missing-fieldsdict/missing-componentsdict/missing-messagesdict/datatype-cycledict/datatype-missing-parentdict/datatype-bad-basedict/field-key-mismatchdict/field-bad-tagdict/field-unknown-typedict/duplicate-field-namedict/duplicate-enum-valuedict/message-missing-msgtypedict/duplicate-msgtypedict/duplicate-message-namedict/unknown-field-refdict/unknown-component-refdict/component-cycledict/unknown-group-counterdict/non-counter-group-headdict/empty-groupdict/unresolvable-group-delimiterparse/empty-inputparse/malformed-fieldparse/missing-begin-stringparse/missing-body-lengthparse/missing-msgtypeparse/framing-orderparse/begin-string-mismatchparse/unknown-msgtypeparse/missing-checksumparse/checksum-mismatchparse/body-length-mismatchparse/unknown-tagparse/tag-not-in-messageparse/duplicate-tagparse/duplicate-groupparse/invalid-group-countparse/group-count-mismatchparse/data-length-mismatchparse/unknown-datatypeparse/invalid-intparse/invalid-floatparse/invalid-booleanparse/number-precisionvalidate/unknown-msgtypevalidate/required-field-missingvalidate/required-group-missingvalidate/empty-valuevalidate/value-not-in-enumvalidate/invalid-valuevalidate/conditional-requiredvalidate/field-outside-layerextend/field-tag-collisionextend/field-name-collisionextend/field-bad-tagextend/field-unknown-typeextend/tag-outside-user-rangeextend/data-length-unwiredextend/enum-unknown-fieldextend/enum-value-conflictextend/component-collisionextend/component-cycleextend/msgtype-collisionextend/message-name-collisionextend/header-trailer-injectedextend/header-trailer-missingextend/target-not-foundextend/unknown-memberextend/member-not-foundextend/duplicate-memberextend/counter-not-markedextend/group-delimiter-shiftextend/ambiguous-boundaryextend/unresolvable-group-delimiterextend/data-length-not-placedextend/counter-as-fieldextend/invalid-specextend/delimiter-definedextend/component-fanout
All 82 codes are catalogued with what each one means and its usual cause in decode diagnostics — every chip above deep-links its row.
ConditionalRuletypesince 0.1.0
type ConditionalRule = (ctx: ConditionalContext) => FixIssue[]Source: packages/fix/src/validate/conditions.ts:42
A conditional ("C", required-by-prose) presence rule. Given a message's state, it returns the FixIssues for any conditionally-required field that is missing (or any forbidden field that is present). Pure and total: it must not throw and must tolerate a dictionary that lacks the fields it references (return []), so a rule written for FIX 4.4 is harmless on a custom dialect.
Supply extra rules via ValidateOptions.conditionalRules.
ConditionalContextinterfacesince 0.1.0
interface ConditionalContextSource: packages/fix/src/validate/conditions.ts:18
The read-only view of one message a ConditionalRule reasons over. A rule inspects top-level fields by tag (or, for dialect-robustness, by spec name) and returns any conditional-presence violations it finds. Group-internal conditions are out of scope for v0.1 (a declared coverage gap — see the package README).
readonly message: ParsedMessageThe message being validated.
readonly def: MessageDefThe resolved definition for
ParsedMessage.msgType.readonly dict: DictionaryThe dictionary, for resolving field names → tags and datatypes.
field(tag: number): string | undefinedThe verbatim wire value of a top-level field, or
undefinedif it is absent.has(tag: number): booleanWhether a top-level field is present.
fieldByName(name: string): string | undefinedThe verbatim wire value of a top-level field looked up by its spec name.
DEFAULT_CONDITIONAL_RULESconstsince 0.1.0
const DEFAULT_CONDITIONAL_RULES: readonly ConditionalRule[]Source: packages/fix/src/validate/conditions.ts:77
The built-in conditional rules. Deliberately small: only the mechanically-unambiguous session-layer rule lives here. The bulk of FIX 4.4's C requirements are free-text prose (a declared v0.1 coverage gap); the data→Length companion rule, which is mechanical, is derived from the dictionary inside the value walk rather than hand-listed here.