Skip to content

Not a Validator

m4bwav edited this page Sep 30, 2026 · 3 revisions

The printer tracks three things: whether it is inside a string, whether the next character is escaped, and which brackets are open. Everything else is copied through. That makes it tolerant of input a parser would reject, and it means the output for broken input is tidy rather than an error. The examples below are the actual output of 3.0.2 (the same as 3.0.1) with the default options.

Input that goes through

A trailing comma stays, and the line break it owes goes before the closing brace:

{"a":1,}
{
    "a": 1,
}

Single-quoted strings are tracked like double-quoted ones, so the space inside stays:

{'a':'b c'}
{
    'a': 'b c'
}

Bare words are just characters:

{a:1,b:[x,y]}
{
    a: 1,
    b: [
        x,
        y
    ]
}

A document that ends before its closing bracket is printed as far as it goes, and an unterminated string swallows whatever follows it:

{"a":1
{
    "a": 1

Two documents in one string, as in a JSON Lines file, run together, because the line break between them is whitespace:

{"a":1}
{"b":2}
{
    "a": 1
}{
    "b": 2
}

Split the lines first and format each one.

A block comment survives, minus its inner spaces:

{"a":1 /* note */,"b":2}
{
    "a": 1/*note*/,
    "b": 2
}

Line comments: the one that bites

A // comment is not whitespace, so its characters are copied, but the spaces inside it and the line break that ends it are whitespace and are dropped. The text after the comment is glued onto it:

{"a":1, // a note about a
"b":2}
{
    "a": 1,
    //anoteabouta"b": 2
}

The output is no longer the document you had. If the input may contain comments, strip them first with System.Text.Json, which drops trailing commas at the same time:

using System.Text.Json;
using System.Text.Json.Nodes;

var lenient = new JsonDocumentOptions { CommentHandling = JsonCommentHandling.Skip, AllowTrailingCommas = true };
var clean = JsonNode.Parse(text, null, lenient)!.ToJsonString();   // compact, comment-free
var pretty = clean.PrettyPrintJson();

The two errors

The printer throws for exactly two things, both FormatException, both naming the zero-based character index in the input as given:

Input Message
{"a":1}} Unexpected '}' at index 7: there is no open object or array to close.
] Unexpected ']' at index 0: there is no open object or array to close.
[1} Unexpected '}' at index 2: expected ']'.
{"a":1] Unexpected ']' at index 6: expected '}'.

A printer that has thrown is fine to reuse; its state is reset at the start of the next call. With the TextWriter overloads, everything before the bad bracket has already been written when the exception arrives.

Null input throws ArgumentNullException, and that is the whole list.

What it cannot tell you

A missing bracket, an unterminated string, a bad escape, a bare word, a duplicate key, a trailing comma: none of these is reported. To know whether text is JSON, parse it first; Recipes shows the short version. The printer is for making text readable, including text that is almost JSON, such as a log line or a config file once its comments are gone.

Clone this wiki locally