How to validate json files for ci/cd pipeline integration
- Step 1Drop the JSON file you're about to commit — Drag the modified config, workflow, or manifest file onto the dropzone, or click to pick it. Parsing runs in your browser — the file is never uploaded. Free tier accepts files up to 2 MB and one file at a time.
- Step 2Leave Strict mode on and click Validate — The 'Strict mode' checkbox is shown for clarity but the parser is strict RFC 8259 regardless — there is no JSONC/comment-tolerant path. Click Validate to run
JSON.parseon the file content. - Step 3Read the verdict and the error position — A green 'Valid JSON' banner means CI will accept it. A red 'Invalid JSON' banner shows the raw parser message plus the character position (and line/column when V8 provides it) — jump to that offset in your editor.
- Step 4Confirm the parsed structure on success — On a pass, the 'Parsed output' panel shows the value re-serialised with 2-space indent. Skim it to confirm a missing comma didn't accidentally make two objects merge or a value land at the wrong nesting level. (Display truncates at 5,000 characters; Copy gives you the full output.)
- Step 5Fix at source, or hand off to the fixer — Hand-fix the reported position, or if the file has many small mistakes (single quotes, trailing commas,
undefined) paste it into json-format-fixer, which applies regex repairs and re-parses. - Step 6Wire the same check into CI — Add an automated gate so nobody bypasses the manual step:
git ls-files '*.json' | xargs -I{} sh -c 'jq empty {} || (echo FAIL: {}; exit 1)'.jq emptyandnode/JSON.parseapply the same RFC 8259 rules this tool uses, so local and CI verdicts agree.
What this validator does — and the sibling tool for what it doesn't
The validator is syntax-only (a thin wrapper over V8 JSON.parse). It deliberately does not lint, fix, or schema-check. Use the right sibling for those.
| You need to… | This tool | Use instead |
|---|---|---|
| Confirm a file is parseable JSON before commit | Yes — pass/fail + error position | — |
Auto-remove trailing commas / fix single quotes / undefined→null | No — it reports the error, never edits | json-format-fixer |
| Re-indent / pretty-print valid JSON for a diff | Shows parsed output, but it's a validator | json-prettifier |
| Generate a JSON Schema to gate structure in CI | No schema features at all | json-schema-generator |
| Detect duplicate keys | No — V8 silently keeps the last value | Review manually; jq won't flag it either |
| Compare config across two environments | No diffing | json-diff |
Hand-edit mistakes that fail CI — and the exact V8 message
Verified against Node's V8 JSON.parse (the engine this tool and your CI's node step share). 'Status' reflects whether CI accepts the file.
| Mistake in the JSON | Example | V8 / CI verdict | Parser message (abbreviated) |
|---|---|---|---|
Trailing comma before }/] | {"a":1,} | Rejected | Expected double-quoted property name … position 7 |
| Single-quoted string or key | {'a':1} | Rejected | Expected property name or '}' … position 1 |
| JS-style comment | {"a":1} // note | Rejected | Unexpected non-whitespace character after JSON |
| Unquoted object key | {a:1} | Rejected | Expected property name or '}' … position 1 |
NaN / Infinity | {"a":NaN} | Rejected | Unexpected token 'N' … is not valid JSON |
| Leading zero on a number | {"a":01} | Rejected | Unexpected number … position 6 |
| Two JSON values (NDJSON in one file) | {"a":1}\n{"b":2} | Rejected | Unexpected non-whitespace character after JSON |
Free vs paid limits for JSON tools
Per-file size limits for the JSON tool family. Validation is single-file regardless of tier.
| Tier | Max file size | Batch files |
|---|---|---|
| Free | 2 MB | 1 |
| Pro | 100 MB | 10 |
| Developer | 5 GB | unlimited |
Cookbook
Real CI/CD JSON failures and how the validator localises them before the push. Inputs are abbreviated; values anonymised.
GitHub Actions matrix JSON with a trailing comma
ExampleA fromJSON() matrix built by hand picks up a trailing comma after the last entry. The workflow doesn't fail at lint time — it fails when the matrix job tries to expand, with a cryptic 'unexpected end of JSON' in the runner. Validating the raw matrix string locally pins it instantly.
Input (matrix.json, pasted to a file):
{
"include": [
{ "node": 18 },
{ "node": 20 },
]
}
Validator output:
Invalid JSON
Expected double-quoted property name in JSON at position 51 (line 5 column 5)
Fix: delete the comma after { "node": 20 }tsconfig.json blocks the build (it's JSONC, not JSON)
Exampletsconfig.json is JSON-with-Comments. TypeScript reads it fine, but a CI step that runs plain JSON.parse/jq on it fails. This validator behaves like that CI step — it rejects the comments — which tells you the script is using the wrong parser, not that your tsconfig is broken.
Input (tsconfig.json):
{
// base options
"compilerOptions": { "strict": true }
}
Validator output:
Invalid JSON
Unexpected token / … is not valid JSON
Takeaway: the file is valid JSONC. Don't run plain JSON.parse/jq on it
in CI — use tsc --showConfig or a JSONC-aware step. Strip the comment
first with json-format-fixer if a step truly needs strict JSON.Two API fixtures concatenated into one file
ExampleA test-fixture generator appended a second response to an existing file, producing two top-level objects. Each half is valid, but JSON allows exactly one top-level value, so the consumer's JSON.parse throws at the boundary.
Input (fixture.json):
{ "id": 1, "ok": true }
{ "id": 2, "ok": false }
Validator output:
Invalid JSON
Unexpected non-whitespace character after JSON at position 24 (line 2 column 1)
Fix: wrap both in an array [ … , … ], or split into two files /
use NDJSON with a line-by-line reader instead of JSON.parse.Diagnosing a deploy log that only says 'position 412'
ExampleA platform deploy rejected a config with SyntaxError … at position 412 and no line number. Pasting the same file content here reproduces the parser message with the same offset, and the pretty-printed surrounding structure makes the missing comma obvious.
Deploy log: SyntaxError: Expected ',' or '}' after property value in JSON at position 412 Validator on the same file: Invalid JSON Expected ',' or '}' after property value in JSON at position 412 (line 18 column 3) Now you have line 18 — the deploy log didn't give you that.
Green here = green in the jq CI gate
ExampleOnce the file passes locally, the automated CI gate accepts it because both use RFC 8259 rules. This is the value of using the same parser on both ends — no 'works on my machine' gap.
Local validator: Valid JSON (1.8 KB)
CI step:
- run: git ls-files '*.json' | xargs -I{} sh -c 'jq empty {} || exit 1'
result: exit 0 — no files rejectedErrors and edge cases
Real errors and silent failures sourced from each platform's own documentation. Match the wording to the row, fix what the row says to fix.
tsconfig.json / .vscode settings (JSONC)
RejectedFiles that use // comments or trailing commas are JSONC, not JSON. This tool runs strict JSON.parse, so it rejects them — and so will any CI step using jq or node. The 'Strict mode' checkbox does not enable comment tolerance; there is no permissive path. If a CI step genuinely needs strict JSON, strip comments first with json-format-fixer.
Trailing comma after the last array/object element
Rejected{"a":1,} or [1,2,] fail with Expected double-quoted property name / Expected value. This is the single most common hand-edit CI failure. The validator points at the comma's position; json-format-fixer removes it automatically.
Duplicate object keys
By design — not flagged{"env":"a","env":"b"} parses successfully and V8 silently keeps the last value ("b"). This validator does not detect duplicate keys — jq and node don't either. If two pipeline stages set the same config key, this passes and the later wins; review duplicates manually.
Multiple top-level values (NDJSON / concatenated)
RejectedJSON permits exactly one top-level value. {...}\n{...} (newline-delimited JSON) fails at the second value with Unexpected non-whitespace character after JSON. NDJSON log/fixture files must be read line-by-line; wrap the lines in a [ ] array if you need a single JSON document.
Leading UTF-8 BOM on the file
SupportedFiles saved by some Windows editors begin with a U+FEFF byte-order mark. The tool calls .trim() before parsing, and U+FEFF is whitespace in ECMAScript, so the BOM is stripped and the file validates. Note other parsers (e.g. some Python or Go readers) do not strip it — a BOM that's fine here can still break a stricter CI step.
Empty file or whitespace-only file
RejectedAn empty config (or one trimmed to nothing) fails with Unexpected end of JSON input. This often means an upstream generator wrote zero bytes — check that the file-producing step actually ran before the deploy step consumed it.
`NaN`, `Infinity`, or `+1` from a serializer bug
RejectedThese are valid JavaScript literals but not valid JSON, so V8 rejects them (Unexpected token 'N'/'I'/'+'). A non-finite number usually means an upstream JS service serialised a division result without guarding it. Fix the producer; the validator can only flag it.
Top-level primitive (`42`, `"ok"`, `true`, `null`)
SupportedRFC 8259 allows a bare scalar as the whole document, so 42 and "ok" validate as 'Valid JSON'. If your consumer expects an object/array wrapper, a bare scalar can still break it downstream even though it's technically valid — the validator's job ends at syntax.
File larger than the 2 MB free limit
BlockedFree tier caps JSON files at 2 MB. Config and manifest files are almost always far below this. A multi-megabyte 'config' usually means embedded data that belongs in a separate file or a database; large bundled JSON validates on Pro (100 MB) or Developer (5 GB).
Unescaped control character inside a string
RejectedA raw tab or newline pasted into a string value (instead of \t / \n) fails with Bad control character in string literal. Common when copying multi-line text into a config value by hand; escape it or move the long text out of the JSON.
Frequently asked questions
Will a file that passes here also pass my CI's JSON check?
Yes, as long as your CI uses an RFC 8259 parser — node/JSON.parse, jq, and python -m json.tool all are. This tool is a thin wrapper over V8 JSON.parse, the same engine your node step uses, so the verdict matches. The exception is JSONC-aware tooling (TypeScript's tsconfig reader, VS Code) which is more lenient than both this tool and a plain jq gate.
Does the 'Strict mode' checkbox let me validate JSON with comments?
No. The checkbox is labelled 'no trailing commas, no comments', but the parser is strict RFC 8259 either way — there is currently no comment-tolerant path. To validate a JSONC file like tsconfig.json, either use a JSONC-aware tool or strip the comments first with json-format-fixer.
Does it do JSON Schema validation, so I can gate structure in CI?
No. This tool validates syntax only (is it parseable JSON). For structural validation, generate a schema with the JSON Schema Generator, then run ajv-cli (npx ajv validate -s schema.json -d 'data/*.json') as a CI step. Syntax-validate first; schema validation only makes sense on syntactically valid JSON.
How do I add an automated JSON gate to GitHub Actions?
Add a step: run: git ls-files '*.json' | xargs -I{} sh -c 'jq empty {} || (echo FAIL {}; exit 1)'. jq empty parses and discards each file, failing the job on the first invalid one. For schema conformance, add an ajv-cli step. This validator is the local pre-check; the gate enforces it for everyone.
Why does my deploy say 'position 412' but no line number?
V8 includes a character offset in every parser error and a line/column when it can compute one, but some platforms log only the position. Paste the same file here — it reproduces the message and, when V8 emits it, the (line N column N) part, giving you the line the deploy log dropped.
Is my config uploaded anywhere?
No. Validation runs entirely in your browser via JSON.parse. The file content — including secrets-adjacent config, IaC, and event payloads — never reaches a JAD Apps server. You can confirm in DevTools: no network request fires on Validate.
Can it validate every JSON file in my repo at once?
No — it's one file at a time (free tier batch is 1). For repo-wide validation use the CLI loop in the steps above (git ls-files '*.json' | xargs … jq empty), which is also what you'd run in CI. This tool is for the focused, single-file check while editing.
Does it catch a missing comma between two array elements?
Yes — [{"a":1} {"b":2}] fails with Expected ',' or ']' after array element, and you get the position of the second object. If you'd rather auto-insert the missing comma, json-format-fixer has a heuristic for that and re-parses the result.
My Kubernetes JSON manifest is valid here but kubectl rejects it — why?
This tool only checks JSON syntax. A manifest can be perfect JSON yet invalid Kubernetes (wrong apiVersion, missing required field). For API-level validation use kubectl apply --dry-run=client -f manifest.json, or kubeconform/kubeval for offline schema checks. Syntax-validate here first so you're not chasing a comma inside a schema error.
Does a trailing newline at the end of the file cause a failure?
No. The tool trims surrounding whitespace before parsing, and a trailing newline is whitespace, so it's ignored. Most formatters add a trailing newline by convention and it never affects validity.
Why does the parsed-output panel cut off?
The on-screen pretty-printed preview is truncated at 5,000 characters to keep the page responsive. The validity verdict is computed on the whole file, not the preview, and the Copy button copies the full re-serialised output regardless of the visible truncation.
What's the difference between this and json-format-fixer for CI?
This validator is read-only: it tells you pass/fail and where the first error is, matching what CI will conclude. json-format-fixer is write: it tries to repair common mistakes (trailing commas, single quotes, unquoted keys, undefined→null, missing commas) and returns corrected JSON. Use the validator to gate, the fixer to repair.
Privacy first
Conversion runs locally in your browser. No file is uploaded — only metadata counters are saved for signed-in dashboard stats.