Docket / Fix it / JSON-LD errors

Read the JSON-LD error, not the guess

Invalid JSON-LD is the most expensive structured-data fault there is, because nothing is partially read: one bad character and the whole block is discarded, so a page with perfect Product markup is treated exactly like a page with none. The report usually shows you the parser's own message — and then, underneath, a list of likely causes that may have nothing to do with it.

The tool had the answer and printed a guess

A check that finds invalid JSON-LD has, by definition, just tried to parse it and caught an exception. It is holding the exact reason. Docket printed that exception and then offered a fixed list of three usual suspects: a trailing comma, an unescaped quote, HTML entities the CMS encoded into the block.

On a consumer-rights body's site, every page checked failed with the same message — Invalid control character — which is none of those three. The real cause was a raw newline inside a string holding HTML, exactly the shape a CMS produces when it writes a multi-line field straight into a script block.

So the reader goes hunting for a trailing comma that does not exist, while the message that would have told them the answer sits above it meaning nothing to anybody who does not write parsers. An error message is evidence; a list of likely causes is a guess. Printing the guess while holding the evidence is the defect.

What each message actually means

This is the part worth keeping. These are the messages a JSON parser emits and what each one means for the person fixing it:

If your tool shows you a message that is not in a list like this, the message is still the better clue than any generic advice beside it. Search for it exactly.

Fixing one error per page is not fixing the page

The second half of this, and the more damaging one.

Docket used to stop at the first broken block on each page. That made its summary sentence unable to be wrong in the only way that matters: "all of them fail the same way" was a statement about what the tool had collected, not about the site. The clause that exists to say "other kinds of error are also present" could never fire, because a second error on an already-recorded page was never looked at.

On a hardware vendor's site every page carried two JSON-LD blocks, and several had both broken, with different errors. The report named one missing comma. Somebody fixes the comma, re-tests, and the page is still discarded by the search engine — which is exactly the outcome the check exists to prevent.

Sampling one instance per page and then summarising across pages produces a claim that cannot be falsified in the way that matters. It is a quiet failure mode, because the summary sounds more confident the less it looked at.

The repair kept the units straight, which is worth copying: the page list stays one entry per page, so the count and the URLs still mean pages, while the error collection gathers every failure so the summary describes the site rather than the sample.

Checking your own markup

When this matters most, and when it does not

It matters most on templated pages that carry commercial markup — products, events, recipes, jobs — because the fault is invisible on the page and total in effect. There is no partial credit.

It matters least where the block was aspirational: markup added for an entity you were never going to earn a rich result for costs you an entity signal rather than a search feature. Fix it, but not first.

The fixes that make it worse

How to make this finding disappear without fixing anything

Delete the script block. The finding clears, the page becomes one with no structured data at all, and no tool will complain — because an absent block and a discarded block look identical to a search engine. That equivalence is the whole reason this fault is worth catching: you already have the outcome of deleting it, and you are paying to generate it.

Where this sits in an audit

The registered check is schema.invalid, which covers JSON-LD that does not parse. For the other structured-data faults — markup contradicting the visible page, required properties genuinely missing, coverage as a judgement rather than an error — see how to fix structured data errors →. For the case where the block parses perfectly and still resolves to nothing, see an @id is a pointer, not a definition →.

Common questions

What does Invalid control character mean in JSON-LD?

A literal newline, tab or carriage return inside a string value. JSON forbids them unescaped, and it is almost always a CMS writing a multi-line HTML field straight into the script block.

My audit lists likely causes that do not match my error. Which do I trust?

The error message. The tool parsed your block and caught the exact exception; a list of usual suspects beside it is a guess that may predate your case.

If one block on a page is invalid, does the rest still count?

Invalid JSON is not partially read — the whole block is discarded. A page can carry several blocks, so fix every one and re-validate rather than stopping at the first.

Why did fixing the reported error not fix my page?

Because there was more than one. A check that records a single error per page can report that they all fail the same way when it only ever looked at one of them.

How do I find which page broke when the template is fine?

Validate the rendered output rather than the template. These faults come from data interpolated without escaping, so they appear only on the records whose text happens to contain a quote or a line break.