Validate
The validate command catches common FHIR mistakes before you submit a resource to a server — format problems, structural issues, and unknown resource types. It’s a fast, local sanity check designed for the development loop.
Basic usage
Section titled “Basic usage”fhir-resource-diff validate examples/showcase/patient-chalmers.json --fhir-version R4valid ℹ For full FHIR schema validation, use the official HL7 FHIR Validator → https://confluence.hl7.org/display/FHIR/Using+the+FHIR+ValidatorA clean resource shows valid. The note about the HL7 Validator is a scope footer — it appears whenever --fhir-version is specified and is not a finding about your resource. valid (with warnings) only appears when the tool actually found something to flag in your data.
Version-aware validation
Section titled “Version-aware validation”fhir-resource-diff validate resource.json --fhir-version R5The --fhir-version flag enables version-aware checks — the resource type is validated against the registry for that specific version, and the HL7 documentation links in output point to the correct version.
Without --fhir-version, the tool auto-detects the version from meta.fhirVersion or defaults to R4.
What this tool checks
Section titled “What this tool checks”| Check | Severity | Description |
|---|---|---|
| Valid JSON | error | Malformed JSON fails immediately |
resourceType present |
error | Required on every FHIR resource |
resourceType non-empty |
error | Empty string is not a valid resource type |
FHIR id format |
warning | Must match [A-Za-z0-9\-.]{1,64} — servers reject silently otherwise |
| Date formats | warning | FHIR uses a strict ISO 8601 subset; 2024/03/15 or 03-15-2024 are caught |
| Reference string format | warning | subject.reference must be ResourceType/id, an absolute URL, #fragment, or urn: — bare IDs like "12345" are flagged |
| Known resource type | info | Checked against the registry for the specified FHIR version |
What it doesn’t check — and why
Section titled “What it doesn’t check — and why”Full FHIR schema validation requires StructureDefinitions from the specification: required fields, cardinality, value set bindings, profile conformance, and invariants. Bundling and keeping those current is a significant maintenance surface.
The HL7 FHIR Validator is the authoritative tool for full conformance. fhir-resource-diff catches the common mistakes that cause server rejections and surface data quality issues — it’s the fast check in your development loop, not the compliance gate in staging.
JSON output format
Section titled “JSON output format”fhir-resource-diff validate patient.json --format json{ "valid": true, "errors": [], "hint": { "message": "For full FHIR schema validation, use the official HL7 FHIR Validator", "url": "https://confluence.hl7.org/display/FHIR/Using+the+FHIR+Validator" }}When there are findings:
{ "valid": false, "errors": [ { "severity": "error", "path": "resourceType", "message": "resourceType is required", "ruleId": "required-resource-type" }, { "severity": "warning", "path": "id", "message": "id must match [A-Za-z0-9\\-.]{1,64}", "ruleId": "id-format" } ], "hint": null}Each error has:
severity—error,warning, orinfopath— dot-notation path to the field with the problemmessage— human-readable descriptionruleId— stable identifier for the rule (useful for suppression or automation)
Severity model
Section titled “Severity model”Only severity: error findings produce a non-zero exit code. Warnings and info findings surface in output but never break pipelines.
| Severity | Exit code | When |
|---|---|---|
| error | 1 | Invalid JSON, missing resourceType |
| warning | 0 | Date format, id format, reference format |
| info | 0 | Unknown resource type, informational notes |
Quiet mode for CI
Section titled “Quiet mode for CI”fhir-resource-diff validate patient.json --quietecho $? # 0 = no errors, 1 = errors found--quiet suppresses all stdout output. Useful when you only need the exit code in a CI step and don’t want to capture or discard output.
Stdin pipe
Section titled “Stdin pipe”# Validate a resource fetched from a FHIR servercurl -s https://hapi.fhir.org/baseR4/Patient/592473 \ | fhir-resource-diff validate - --fhir-version R4
# Validate from a variable (no temp file needed)echo "$FHIR_PAYLOAD" | fhir-resource-diff validate - --format json --fhir-version R4Use - as the file argument to read from stdin.
Multi-resource input
Section titled “Multi-resource input”validate auto-detects whether the input is a single JSON object, a JSON array, or NDJSON (one resource per line) — no flag required. This works for both file paths and stdin (-).
# JSON array file by pathfhir-resource-diff validate patients.json
# NDJSON file by pathfhir-resource-diff validate patients.ndjson
# JSON array via stdincat resources.json | fhir-resource-diff validate -
# NDJSON via stdincat resources.ndjson | fhir-resource-diff validate -
# Single resource — unchanged behaviourfhir-resource-diff validate patient.jsonMulti-resource text output (file path or stdin)
Section titled “Multi-resource text output (file path or stdin)”[1/3] Patient/abc123valid
[2/3] Patient/def456invalid ✗ resourceType: resourceType must be a non-empty string
[3/3] Observation/ghi789valid
---3 resources: 2 valid, 1 invalidEach block has a [index/total] ResourceType/id header (ResourceType (no id) when id is absent). A summary line follows the last block. A single-element array uses the existing single-resource output format (no header, no summary).
Multi-resource JSON output
Section titled “Multi-resource JSON output”cat resources.json | fhir-resource-diff validate - --format json[ { "index": 1, "resource": { "resourceType": "Patient", "id": "abc123" }, "valid": true }, { "index": 2, "resource": { "resourceType": "Patient", "id": "def456" }, "valid": false, "errors": [ { "path": "resourceType", "message": "resourceType must be a non-empty string", "severity": "error" } ] }]--envelope wraps the array in the standard metadata envelope when combined with --format json.
Exit codes for multiple resources
Section titled “Exit codes for multiple resources”| Condition | Exit code |
|---|---|
| All resources valid (no errors) | 0 |
| At least one resource has error-severity issues | 1 |
| Input could not be parsed at all | 2 |
Empty input
Section titled “Empty input”echo "[]" | fhir-resource-diff validate -# stdout: 0 resources validated# exit 0Annotate wrapper interop
Section titled “Annotate wrapper interop”When validate - receives an --annotate wrapper produced by fhir-test-data generate --annotate, it automatically detects and unwraps it:
fhir-test-data generate patient --annotate | fhir-resource-diff validate -# stderr: Note: detected --annotate wrapper; validating inner resource# stdout: validDetection is automatic — no flag required. The wrapper format is { "resource": {...}, "notes": [...] }.
With –envelope
Section titled “With –envelope”fhir-resource-diff validate patient.json --format json --envelope{ "tool": "fhir-resource-diff", "version": "0.2.0", "command": "validate", "fhirVersion": "R4", "timestamp": "2026-03-14T15:56:25.686Z", "result": { "valid": true, "errors": [], "hint": null }}The envelope adds tool version, FHIR version, and timestamp — useful for audit trails and automated pipelines that need to know when and how a validation was run.
See also
Section titled “See also”- Exit codes — full severity model and exit code table
- Output formats — text, JSON, markdown, envelope
- CLI reference — all flags for
validate