I fixed 4 broken JSON-LD blocks at 3pm. Google found 32 more at 8pm.
At 15:40 I finished patching four pages where an affiliate link had been injected inside a JSON-LD block. I rewrote the safety check, re-ran the verifier, got zero failures, deployed. Felt done.
At 20:44 an email from Google Search Console arrived:
Unparsable structured data. Parsing error: Missing ',' or '}'
On a different site. Different pages. Same root cause.
What actually happened
Months earlier I wrote a script that inserts internal links into article bodies. It was a naive string operation: find anchor text, wrap it in an <a href="..."> tag.
The problem is that href="..." contains double quotes. JSON-LD lives inside a <script type="application/ld+json"> block, and a JSON string cannot contain a raw double quote. Every FAQ answer that got a link injected became unparsable JSON. The whole block — including the valid FAQPage markup around it — was dead.
GSC reported one affected page. A full scan found 32 broken blocks across three sites: 27 on one, 3 on another, 2 on a third. Two sites were clean, purely because nobody had run the link-injection script on them.
The part that bothers me
My own checker had reported zero failures on all three sites that same week. It was green the entire time this was broken.
The reason is simple and embarrassing: my verifier validated the things I was worried about. Titles, canonicals, link attributes, image alt text, ads.txt. It never parsed the JSON-LD. I had written a checker for the failure modes I had already imagined, and this was not one of them.
Google submitted to the same pages my checker passed and got a different answer, because Google actually parses structured data and my script didn't.
Two bugs, one class, one day
The afternoon fix and the evening discovery are the same bug with different entry points:
- 15:40 — affiliate link injection wrote an anchor into a JSON-LD block. My "safe spot" heuristic checked the first 300 characters of the file and missed script blocks that opened earlier than that. Four pages hit.
- 20:44 — internal link injection had done the same thing months earlier and I never noticed, because nothing was watching. Thirty-two blocks hit.
I patched symptoms at 15:40. The class of bug wasn't addressed until 20:44, and only because an external system told me.
What I changed
Three rules, all cheap:
- Any script that writes into HTML must first map the
<script>and<style>regions and treat them as off-limits. Not "check the first N characters" — build the actual exclusion ranges. My 300-character window was a guess dressed up as a check. - The verifier now parses every
ld+jsonblock with a real JSON parser and fails the build if any one is unparsable. Not regex.json.loads. - When injecting into a JSON string, escape or strip. I chose stripping: remove the
<a>tag, keep the anchor text. An FAQ answer reads fine without a hyperlink, and structured data validity is worth more than one internal link.
The general lesson
A local checker only tells you about the questions you asked it. Every green run I had was real — and every one of them was silent about structured data, because I had never asked.
The fix isn't a better checker. It's treating external systems as the second opinion they are. GSC, browser consoles, and third-party validators cost nothing and catch the category you forgot existed. In my case the gap between "my tool says fine" and "Google says broken" was five hours and 28 pages.
If you want a second pair of eyes on your structured data or your site's search setup: /