Skip to content

Validating feeds

This guide walks through a realistic validation loop: pick the right output format, filter out noise, produce a report for a stakeholder, and iterate until the feed is clean.

gapline validate can emit five formats. Match the format to the consumer.

FormatBest for
textInteractive use. Colored by default; colors disable automatically on a non-TTY pipe.
jsonCI pipelines. Parseable with jq, diffable across runs.
csvSpreadsheet triage. One row per finding.
xmlLegacy systems that already ingest GTFS validator XML.
htmlShare a report with a non-technical stakeholder. Self-contained, open by double-click.
Terminal window
gapline validate -f gtfs.zip --format json -o report.json
gapline validate -f gtfs.zip --format html -o report.html
gapline validate -f gtfs.zip --format csv -o report.csv

The full schema of each format is documented on output formats.

By default, every finding is included. The exit code is non-zero only if any finding is at ERROR-level.

If the raw output is too noisy, use --min-severity to hide anything below a chosen level. This also reclassifies — a WARNING with --min-severity warning becomes gate-blocking.

Terminal window
# Fail the run on ERRORs only (default behavior).
gapline validate -f gtfs.zip
# Also fail on WARNINGs.
gapline validate -f gtfs.zip --min-severity warning
# Fail on anything, including INFO suggestions.
gapline validate -f gtfs.zip --min-severity info

See concepts / severities for the policy behind the three levels.

Sometimes a rule is too strict for your feed. A typical example: block_id_trip_overlap fires when you intentionally chain two trips via a shared block_id. Disable it for this run:

Terminal window
gapline validate -f gtfs.zip --disable-rule block_id_trip_overlap

Several IDs can follow a single --disable-rule:

Terminal window
gapline validate -f gtfs.zip --disable-rule block_id_trip_overlap duplicate_coordinates

Find the ID of a rule you want to silence with gapline rules list and a grep:

Terminal window
gapline rules list | grep -i speed

For a permanent silence, pin the list in gapline.toml:

gapline.toml
[validation]
disabled_rules = ["block_id_trip_overlap", "duplicate_coordinates"]

--disable-rule on the CLI appends to the config list, it does not replace it. Shell completion suggests registered IDs dynamically — enable completion if you have not already.

Terminal window
gapline validate -f gtfs.zip

Colored text. Scan it, fix the errors, re-run.

Terminal window
gapline validate -f gtfs.zip --format json -o report.json

Parse the JSON with jq to post comments on a pull request or to produce a diff versus the previous run:

Terminal window
jq '.summary' report.json
jq '.errors | group_by(.rule_id) | map({rule: .[0].rule_id, count: length})' report.json
Terminal window
gapline validate -f gtfs.zip --format html -o report.html

The HTML file is self-contained — CSS and JS are inlined. Email it, or host it somewhere static. No server needed.

The goal is not to run validate once; it is to make running it part of the cadence that keeps your feed healthy.

.git/hooks/pre-commit
#!/usr/bin/env bash
if git diff --cached --name-only | grep -q '^data/gtfs/'; then
gapline validate -f ./data/gtfs/ --min-severity error || exit 1
fi