Fixed-width parser config builder
Outcome
A FIXED_WIDTH feed's parser config (ingestion.source_feed.parser_config)
is authored visually, validated against a sample, and saved without a
migration.
Prerequisites
ingestion.create(write) andingestion.read(dry-run preview).- A small (≤ 50 lines) representative sample on hand.
- Feed type set to
FIXED_WIDTH(or be ready to flip fromCSV).
Pre-flight
Confirm the feed is
FIXED_WIDTH. If you're inheriting an SFTP roster drop seeded asCSV, flip the column first:UPDATE ingestion.source_feedSET feed_type = 'FIXED_WIDTH'WHERE source_feed_id = '<id>';The Parser Config tab is hidden until the feed type matches.
Pull a small representative sample. EBCDIC samples work for the dry-run only if you transcode them upstream — the parser rejects EBCDIC at run time pending a pilot.
Build the schema (Visual pane)
Navigate to
Configuration → Ingestion → Feeds → <feed> → Parser Config.FileMeta block: set encoding + framing.
Framing When newlineNewline-delimited rosters (most common). record-lengthMainframe / AS-400 contiguous-byte exports — enter bytes-per-record. Records: add HEADER + DETAIL + TRAILER (or just one DETAIL for flat layouts). For multi-record schemas every record needs a Discriminator start + Discriminator value — the literal byte at the offset that identifies the record type (typically
H/D/Tat offset 0).Fields: declare each field's
name,start(0-based),length,type. The grid validates inline:Failure Why Duplicate names within a record Rejected Overlapping ranges Highlighted red datetypes withoutdateFormatRejected impliedDecimalson non-numberRejected Expectations (collapsed by default at the bottom of each record):
detailCountFieldon the TRAILER — a numeric field that should equal the count of DETAIL rows.hashField+hashFieldSourceto verify a sum-of-DETAILs total.
These run as soft checks: mismatches surface as
validationErrorsin the dry-run summary instead of failing the parse.
Preview against a sample
Switch to the Preview pane.
Paste up to ~50 lines from the sample file into Sample input.
Click Run preview. The server runs
parseFixedWidthFilewith the unsaved schema and returns the first 50 parsed rows + the summary. The result table highlights every field column declared on each record.Inspect the summary banner:
Counter What Parsed rowsMatch the row count you pasted (modulo trailing blank lines). HEADER / DETAIL / TRAILERReflect role assignments — a 0forDETAILusually means the discriminator at offset 0 doesn't matchDfor any DETAIL row, so the parser left them underrecordType=UNKNOWN.validationErrorsDETAIL_COUNT_MISMATCH/HASH_TOTAL_MISMATCHfrom your expectations. Soft — the rows still parse — but a mismatch in production fails the SLA check.
Save and activate
Save parser config writes the JSON onto the JSONB column. The server zod-validates again on PATCH; an invalid schema reaches the column only if you bypass the UI.
No separate activation flag — the next inbound batch processed by the
process-batchworker picks up the schema viaIngestionService.getParserConfig.To roll back, open the YAML pane, copy the previous JSON from git history (or the prior version of
parser_configfrom PITR), paste, save.
Common pitfalls
| Symptom | Cause | Fix |
|---|---|---|
DETAIL_COUNT_MISMATCH expected 99 actual 12 | TRAILER's detailCountField points at the wrong byte range, OR file truncated at source | Re-run preview; if 12 looks right, the sample is incomplete. |
shorter than required for field X | A field's start + length exceeds row width | For newline-framed files this usually means a vendor padded only the body and trimmed trailing whitespace. Shrink the field or accept shorter rows after re-checking the vendor spec. |
VALIDATION_ERROR on save | Visual pane permits invalid intermediate states | Switch to YAML pane for line-level Monaco markers; fix; save. The wire response includes the full zod issue list under details.issues. |
records is empty after save | JSONB serializes the whole document on PATCH; an empty visual pane writes {records:[]} not null | Send parserConfig: null instead — explicitly clears the column. |
Validation
| Check | Expected |
|---|---|
| Schema-valid badge | Green before Save |
| Dry-run preview | Reasonable HEADER/DETAIL/TRAILER counters |
parser_config after save | JSONB matches the schema |
| Next inbound batch | Parses with the new schema |
Cross-references
- Mapping editor for the transform side that runs after parsing.
- Feed admin for poll config + retry.