Skip to content
All AI readability rules
WarningShared Core8 of 40 ptsStructured Data

How to fix: Missing or invalid JSON-LD

Structured data is a JSON-LD block embedded in a page's HTML that names the entities on that page in schema.org vocabulary, and it must both parse cleanly and declare a recognized @type: add a valid block describing what the page is — an Organization, Article, Product, FAQPage, or LocalBusiness — so an engine can identify the entity rather than infer it from prose.

The check

What is this?

Structured data is a block of JSON-LD in your HTML that names the entities on the page — the organization, the article, the product, the FAQ — in a vocabulary machines already share. AccessKnight looks for those blocks, checks that each one parses, and checks that at least one declares a type it recognizes.

The value is disambiguation. Prose requires a reader to infer that Northwind Coffee is a business, that the number beside it is a price, and that the questions near the bottom are a FAQ. A JSON-LD block states all three as fact, in a format that needs no interpretation. That is why the check is scored in two halves: a block that does not parse states nothing, and a block with an unrecognized type states something the module cannot act on.

Most failures are syntax, not strategy. A trailing comma left by a hand edit, a smart quote pasted in from a CMS field, an unescaped double quote inside a business name, or a template variable rendered without quotes will all throw on parse. The block still looks correct in the page source, which is exactly why it survives — nothing visibly breaks, and the error only appears when something tries to read it.

The impact

Who does this affect, and why does it matter?

Answer engines and the search indexes behind them. Google reads schema for rich results and feeds the same index that backs AI Overviews and AI Mode. OpenAI's OAI-SearchBot fetches pages to surface them in ChatGPT's search features, and Perplexity and Claude parse page markup directly. Each of them is deciding what entity your page is about.

There is no disabled-user story here, and inventing one would be dishonest — screen readers do not read JSON-LD, and none of the 33 WCAG rules covers it. This is one of two Shared Core checks with no WCAG counterpart, alongside server-rendered content. The person it affects is the site owner: your entity gets described by what the markup states, not by what a reader might infer from prose.

AccessKnight scores this at 8 of the 40 Shared Core points, split into two independent halves: 4 points for parsing cleanly and 4 for carrying a recognized type. That split is why a half score is possible at all: a page can parse cleanly and still carry no recognized type, or carry a recognized type in a block that fails to parse.

The parse half is the one that quietly costs points, because errors are tallied across the whole page: one malformed block drops the parsing award from 4 to 2 even when three others are perfect. Be exact about what fixing it does. Google states plainly that markup guarantees no feature, and that its AI surfaces need no special optimization. Valid JSON-LD makes the entity machine-readable. It does not make it cited, and anyone selling it that way is selling theater.

The fix

How do I fix it?

Validate every JSON-LD block on the page, not just the one you suspect, because a single parse error costs all of them the parsing points. Then confirm at least one block declares a recognized type at the top level or inside @graph. Most failures here are a stray comma or a smart quote, not a modelling mistake.

  1. Open View Source and find every script element with type="application/ld+json". The attribute value must match exactly — a type of "application/ld+json; charset=utf-8" is not selected by this check.
  2. Copy each block into a JSON validator or run JSON.parse on it in the browser console. Look for trailing commas, smart quotes from a CMS field, unescaped double quotes inside a name, and template variables rendered without quotes.
  3. Fix every block, not just the obviously broken one — parse errors are counted across the whole page, so a single bad block costs the parsing points for all of them.
  4. Confirm at least one block declares an @type from the recognized set: Organization, WebSite, WebPage, Article, BlogPosting, NewsArticle, Product, FAQPage, QAPage, BreadcrumbList, LocalBusiness, Person, HowTo, Review, or Offer.
  5. Put that type at the top level of the block, inside a top-level array, or inside @graph. A type nested under mainEntity, publisher, or a similar property is not collected by this check.
  6. Re-scan with AccessKnight and confirm the finding lists your types by name with no parse errors reported.
<head> — Before
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "LocalBusiness",
  "name": "Northwind Coffee",
  "telephone": "+1-555-0142",
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "18 Mill Rd",
    "addressLocality": "Bettendorf",
  }
}
</script>

<!-- Trailing comma after "Bettendorf" throws on JSON.parse.
     AccessKnight reports: 1 JSON-LD block(s), 1 with parse errors;
     types: none.  →  2 of 8 -->
<head> — After
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "LocalBusiness",
  "name": "Northwind Coffee",
  "telephone": "+1-555-0142",
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "18 Mill Rd",
    "addressLocality": "Bettendorf"
  }
}
</script>

<!-- One character removed.
     AccessKnight reports: 1 JSON-LD block(s); types: localbusiness.  →  8 of 8 -->
Detection

How does AccessKnight detect this?

AccessKnight selects every script element whose type attribute is exactly application/ld+json, counts them, and runs JSON.parse on each block's contents. Scoring is two independent halves out of 8. The first 4 points are for parsing: at least one block present with zero parse errors earns 4, while at least one block present with any parse error anywhere earns 2 — one malformed block costs the others their points, because errors are tallied across the page rather than per block. The second 4 points are for relevance: at least one @type must match a fixed set of fifteen recognized values — Organization, WebSite, WebPage, Article, BlogPosting, NewsArticle, Product, FAQPage, QAPage, BreadcrumbList, LocalBusiness, Person, HowTo, Review, and Offer — compared after lowercasing, so capitalisation does not matter. The type walker reads @type on the top-level object, iterates a top-level array, and descends into @graph, but it does not walk arbitrary nested properties, so a type buried under mainEntity or publisher is never collected. Two limits are worth stating plainly rather than discovering. Types outside those fifteen, including TechArticle, SoftwareApplication, and Service, are perfectly valid schema but earn no relevance points in this build, so a page whose only markup is a correct TechArticle scores 4 of 8. And microdata and RDFa are not read at all — a page marked up entirely with itemscope and itemprop attributes scores 0, because this check looks only for JSON-LD script blocks.

On screen right now

What strings mean this?

If one of these strings is in front of you right now — in a config file, an HTTP header, an AccessKnight report, or another checker’s output — it is describing the failure explained on this page.

AccessKnight report
Structured data (JSON-LD)
AccessKnight report
No JSON-LD found.
AccessKnight report
Add valid JSON-LD (Organization, Article/Product, FAQPage as relevant) to make entities machine-readable.
HTML
<script type="application/ld+json">
FAQ

Frequently asked questions

Does schema markup help with ChatGPT or AI search?

It states what the page is instead of leaving it to be inferred. An engine reading prose has to work out that a page is about a business, a product, or a set of questions; a JSON-LD block declares it in a shared vocabulary that needs no interpretation. That removes ambiguity about the entity. It is not a mechanism that causes any engine to cite you, and nobody should sell it as one.

Which schema types does AccessKnight recognize?

Fifteen: Organization, WebSite, WebPage, Article, BlogPosting, NewsArticle, Product, FAQPage, QAPage, BreadcrumbList, LocalBusiness, Person, HowTo, Review, and Offer. Types outside that list are still valid schema and still earn the parsing points, but they do not earn the relevance points in this build — so a page whose only markup is a correct TechArticle or SoftwareApplication scores 4 of 8 rather than 8 of 8.

My schema is valid but I only scored 4 of 8. Why?

Because the 8 points are two separate awards. Four are for having at least one block that parses with no errors anywhere on the page, and four are for at least one recognized @type. Scoring exactly 4 means you earned one half and missed the other: either your markup parses but declares a type outside the recognized fifteen, or it declares a recognized type while another block on the page fails to parse.

Does microdata or RDFa count?

No. This check selects script elements with type="application/ld+json" and reads nothing else, so a page marked up entirely with itemscope and itemprop attributes scores 0 here. That is a limit of the check rather than a judgment about microdata. If your markup is in microdata and you want the points, add an equivalent JSON-LD block; the two can coexist.

Where should the @type go in my JSON-LD?

At the top level of the block, inside a top-level array, or inside @graph. The type walker reads @type on the root object, iterates arrays, and descends into @graph, but it does not walk other nested properties. A FAQPage declared under mainEntity of a WebPage is not collected, so the type you want recognized should not be buried inside another entity.
Sources

Where does this come from?

Every external claim on this page traces to one of the documents below — the vendors’ and standards bodies’ own documentation. What AccessKnight adds is the scan, not the standard.

Is this check
failing on your site?

AccessKnight scans any page against all 18 AI-readability checks — including this one — and shows every issue with a fix. Free, no credit card.

✓ Free — no credit card✓ Nothing installed on your site✓ WCAG + AI readability