LLM Output JSON Guardrail Validator

Validates JSON typically pasted from an LLM's output against a checklist of practical guardrails: strict syntax with specific near-miss diagnosis, forbidden non-JSON literals, runaway nesting depth, duplicate keys, and optionally a list of required top-level keys. A free online tool from Staaarter, right in your browser.

Runs locallyUpdated 2026-07-26

Overview

Introduction

Parsing JSON straight out of an LLM's response and trusting it blindly is a common source of quiet bugs: the model might emit a trailing comma, repeat a key with two different values, or nest so deeply it's clearly stuck in a loop, and a bare `JSON.parse` either throws a generic error or, worse, succeeds while silently dropping data. This tool runs a specific checklist of guardrails built around exactly the failure modes LLMs actually produce.

Instead of a single pass/fail boolean, it reports each guardrail's status individually, syntax validity, forbidden literals, nesting depth, duplicate keys, and optionally your own required top-level keys, with concrete detail for every issue found.

What Is LLM Output JSON Guardrail Validator?

A practical validator for JSON that's typically been pasted from an LLM's response, built around a lenient tokenizer that can inspect the raw text even when it doesn't fully parse, so it can diagnose specific near-misses (trailing commas, single quotes, unquoted keys) instead of only relaying `JSON.parse`'s generic error.

It checks five things: strict JSON syntax validity with specific diagnosis on failure; the presence of `NaN`, `Infinity`, or `undefined` literals (technically invalid JSON, but sometimes emitted by models); nesting depth beyond a configurable threshold (default 20 levels), a common sign of runaway generation; duplicate keys within the same object, which `JSON.parse` silently resolves by keeping only the last value; and, if you supply a comma-separated list, which of your expected top-level keys are missing.

Every check reports a clear pass, fail, or skipped status with a human-readable detail string, and fail statuses include the specific items involved (which literals, which duplicate paths, which missing keys) rather than just a count.

How LLM Output JSON Guardrail Validator Works

The validator first attempts a strict `JSON.parse`. If that succeeds, the syntax check passes outright. If it fails, a lenient tokenizer (which, unlike `JSON.parse`, accepts single-quoted strings and bare identifiers instead of throwing) scans the raw text for the three most common LLM near-misses: a comma immediately before a closing `}` or `]`, a string delimited with `'` instead of `"`, and a bare identifier immediately followed by `:` in a key position. Whichever of those it finds are reported specifically; if none are found, the native parser's own error message and location are shown instead.

The forbidden-literal and duplicate-key checks both run directly on that same token stream, independent of whether the strict parse succeeded, since duplicate keys are already invisible by the time a value has been parsed. Nesting depth and the required-keys check need an actual parsed value to inspect: they use the strict parse result when available, or a best-effort auto-corrected parse (quoting unquoted keys and single-quoted strings, stripping trailing commas, replacing forbidden literals with null) when it isn't, clearly noting when a result is based on that auto-correction rather than the original text.

When To Use LLM Output JSON Guardrail Validator

Use it right after an LLM call that's supposed to return structured JSON, before you parse and act on the result in your application, to catch the specific failure modes that a plain `JSON.parse` either can't diagnose or can't even detect.

It's also useful while iterating on a prompt: pasting a handful of real model outputs through this checklist quickly shows whether your prompt reliably produces clean JSON, or whether it's prone to trailing commas, duplicate keys, or runaway nesting that you should address with a stricter prompt, a JSON mode/schema constraint, or a repair step.

Features

Advantages

  • Diagnoses specific near-miss syntax issues (trailing commas, single quotes, unquoted keys) instead of a single generic parse error.
  • Catches duplicate keys, a class of bug `JSON.parse` can't detect at all since it silently keeps only the last value.
  • Flags excessive nesting depth as a proxy for runaway or looping generation, before it causes performance or stack-depth problems downstream.
  • Optional required-key checking lets you verify a specific contract (the fields your code actually needs) in the same pass, not just generic JSON validity.

Limitations

  • The near-miss diagnosis (trailing commas, single quotes, unquoted keys) covers the most common LLM JSON mistakes, not every conceivable one; an unusual malformation may still fall back to the native parser's generic error message.
  • The best-effort auto-correction used for nesting-depth and required-key checks when strict parsing fails is a heuristic text transformation, not a real JSON5-style parser; it can fail to recover a value from more unusual malformations, in which case those two checks report as skipped rather than guessing.
  • This tool doesn't fix or repair JSON, it only diagnoses it; you still need to correct the output yourself or with a dedicated JSON-repair tool before using it.
  • Nesting-depth and duplicate-key detection operate on structural tokens, not semantics; they can't tell you whether the values themselves are correct, only whether the document's shape looks sound.

Examples

A trailing comma diagnosed specifically

Input

{"id":1,"name":"Ada",}

Output

syntax: fail - Trailing comma(s): trailing comma before "}" at line 1, column 22

Instead of a generic "Unexpected token }" message, the specific trailing comma and its location are reported.

A duplicate key that JSON.parse would silently resolve

Input

{"id":1,"id":2}

Output

duplicate-keys: fail - Found 1 duplicate key(s). items: ["$.id"]

JSON.parse(input).id would simply be 2 with no indication the first value was ever there; this check surfaces the duplication itself.

Missing a required top-level key

Input

{"id":1}

Output

required-keys: fail - Missing 1 required key(s). items: ["name"]

With "id, name" entered as the required keys list, the missing "name" key is reported by name.

Best Practices & Notes

Best Practices

  • Run this checklist immediately after receiving an LLM's response and before you parse it for real use, so failures surface before they reach application logic.
  • Enter your actual required top-level keys whenever you know them; a generic syntax pass doesn't tell you whether the specific fields your code depends on are present.
  • Treat a "skipped" status as informative, not as a pass; it means the check couldn't run, usually because the syntax errors were too severe for the auto-correction to recover from.
  • If the same near-miss (trailing commas, say) keeps showing up across many generations, fix it in the prompt or add a JSON-mode/schema constraint at the model level rather than only catching it after the fact.

Developer Notes

The tokenizer is intentionally lenient compared to `JSON.parse`: it accepts single-quoted strings and bare identifiers as tokens instead of throwing, which is what lets the near-miss diagnosis and duplicate-key detection work even on text that wouldn't parse at all. Duplicate-key detection tracks a stack of object/array frames and, for each object frame, a Set of keys already seen plus the most recently seen key (used to build a dotted/bracketed JSON path for reporting); it never needs a successful `JSON.parse` to work. The best-effort auto-correction used for nesting-depth and required-key checks is a set of targeted regex replacements, not a general-purpose JSON5 parser, and is clearly labeled in the output whenever a check's result depends on it.

LLM Output JSON Guardrail Validator Use Cases

  • Validating structured output from an LLM API call before parsing it in an application.
  • Debugging why a prompt intermittently produces JSON your code can't parse.
  • Auditing a batch of saved LLM responses for structural quality before using them as training or eval data.
  • Checking that an LLM's JSON output includes every field a downstream schema or database insert requires.

Common Mistakes

  • Wrapping LLM output in a bare `try { JSON.parse(...) } catch` and treating a caught error as the only possible failure mode, missing that duplicate keys parse successfully while silently dropping data.
  • Ignoring a "skipped" nesting-depth or required-keys result as if it were a pass, when it actually means the check couldn't run due to unresolved syntax errors.
  • Assuming the required-keys check validates types or values; it only checks that the key names are present at the top level.

Tips

  • Pair with the JSON Fixer when you need to actually repair the document, not just diagnose what's wrong with it.
  • If nesting depth keeps failing on legitimate data, raise the threshold rather than ignoring the check entirely, so a true runaway generation is still caught.
  • Use the required-keys field even for a quick one-off check; typing a short comma-separated list is faster than eyeballing a large JSON blob for a missing field.

References

Frequently Asked Questions