Yesterday morning my author page was the first AI Search hit for my own name. By afternoon it was buried. Amazon Author Central had taken its place. Nothing about my content changed. What changed was structured data — and the bug was so subtle it passed every standard validator.
If you're publishing JSON-LD across a network of related sites and your AI Search visibility just dropped, this is probably the bug.
What broke
A few weeks ago I ran a sweep across seven sites I own — one author hub, six book companion sites — adding a canonical Person entity with the same @id everywhere. The idea was sound: tell Google AI Mode "all these pages describe the same person, here's the canonical IRI."
What actually got published was five separate inline Person blocks per page, each with the full set of properties — name, given/family names, sameAs URLs — and each at the same @id. On paper that should merge into one entity. In practice, the five blocks had subtly different values. One block had alternateName: "Joshua Watte" as a string. The next block had alternateName: ["Joshua Watte", "Josh Watte", "J Watte", "Joshua A. Watte"] as an array. The sameAs lists varied between 14 and 4 URLs depending on which block was rendered first.
JSON-LD spec is honest about this: when two objects share an @id and disagree on a property type, merge behavior is undefined. Different parsers handle it differently. Google's Knowledge Graph apparently picked the safest path — drop both, fall back to whichever external profile had the most consistent identity signal. That was Amazon Author Central, which had been crawling my book pages for months.
The schema.org validator was happy. The Google Rich Results Test was happy. AI Mode quietly dropped me.
The healthy pattern
You only need the full entity inline once per page. Everywhere else, reference it by @id:
{ "@type": "Book",
"author": { "@id": "https://yoursite.com/#yourname" },
"publisher": { "@id": "https://yoursite.com/#yourname" }
}
JSON-LD resolvers merge that reference into the canonical inline node by IRI. You get one clean entity. Properties don't conflict because they're only declared once.
The canonical inline block can live in a standalone <script type="application/ld+json">:
{ "@context": "https://schema.org",
"@type": "Person",
"@id": "https://yoursite.com/#yourname",
"name": "Your Name",
"alternateName": ["Variant 1", "Variant 2"],
"givenName": "Your",
"familyName": "Name",
"mainEntityOfPage": "https://yoursite.com/about/",
"url": "https://yoursite.com/",
"image": "https://yoursite.com/images/headshot.jpg",
"jobTitle": "What you do",
"sameAs": [
"https://www.linkedin.com/in/...",
"https://gravatar.com/...",
"https://orcid.org/...",
"..."
]
}
That's it. One per page. Every other reference is { "@id": "..." }.
The delta exception
Sometimes a referenced entity needs to add a relation that doesn't exist on the canonical, like worksFor linking a Person to an Organization on a specific page. You don't have to inline the full Person to add that relation. JSON-LD merges by @id, so a sparse delta works:
{ "@type": "Person",
"@id": "https://yoursite.com/#yourname",
"worksFor": { "@id": "https://employer.com/#org" }
}
The canonical name, sameAs, image, etc. all flow in from the inline definition elsewhere. The delta just adds the relation.
How to catch this before it hurts you
I added two checks to my analyzer suite after this:
- Mega Analyzer Schema tab now has an "Entity anchors" section that counts inline blocks per
@idand flags property-value conflicts (string vs arrayalternateName, divergentsameAsdepths). - Schema Validator surfaces "Duplicate inline @id" as a top-level finding with the exact
@ids and the specific conflicts.
Both will tell you which @id is duplicated, how many inline blocks share it, and which properties disagree. The fix is mechanical: keep the first one, replace the rest with { "@id": "..." } references, redeploy.
What this looked like in practice
Six book sites, one author hub, ~330 tool pages, and a Spanish-language version of one site. After the fix:
- Each page had one inline Person block at the canonical
@id. - Every
author,publisher,founder,creator, andworksForfield that used to be a duplicated inline Person became{ "@id": "https://jwatte.com/#ja-watte" }. - The seven-site network now declares a clean star topology: one canonical Person entity, twelve cross-confirming book URLs, plus the off-site identity anchors (Gravatar, Linktree, ORCID, Goodreads, BookBub, LinkedIn, Medium, Amazon Author Central).
AI Mode picked me back up within a couple of days. The lesson: Google's entity resolver is forgiving of sparse data but unforgiving of contradictory data. If you've got the same entity declared multiple times on one page, the only safe thing is to make sure they all agree — and the easiest way to make sure they all agree is to only declare it once.
A second failure mode
While I was at it, the diagnostic on one of my pages also surfaced another silent killer: six Book JSON-LD blocks on the homepage that didn't parse at all. Earlier in the day, a refactor had stringified one of the inline Person objects into the author field of each Book, then left the original spread Person properties hanging below. Each block was syntactically broken JSON. Google was dropping every Book entity on the page.
The schema.org validator forgave it. The Google Rich Results Test silently ignored the broken blocks. The only way I caught it was a manual JSON.parse on every <script type="application/ld+json"> extracted from the rendered HTML.
That's now a check I run before every deploy:
const blocks = [...html.matchAll(
/<script type="application\/ld\+json">([\s\S]*?)<\/script>/g
)];
blocks.forEach((m, i) => {
try { JSON.parse(m[1]); }
catch (e) { console.log(`Block ${i}: FAIL — ${e.message}`); }
});
Fifteen seconds. Catches every parser-broken block. Worth wiring into your build.
Related reading
- Entity anchors and the Knowledge Graph — the kgmid, Maps cid, GBP, and dual-typing signals that make AI Search treat a name-only query as resolvable.
- Gravatar and Wikidata as entity signals — the off-site identity anchors AI Search treats as third-party verification.
- Mega Analyzer — runs both the duplicate-inline check and the AI Eligibility composite that surfaces the issue at a glance.
- Schema Validator — top-level finding when an
@idis declared with multiple inline blocks.
If you've been working on entity binding for a small or indie operation, my book The $97 Launch has a chapter on building the off-site profile stack for under a hundred bucks — Gravatar, Linktree, ORCID, the major industry directories, plus the patterns above that let one canonical entity carry across a network of related domains. The chapter is mostly a checklist; if your name was just demoted in AI Mode like mine was, it's the cheapest fix you'll find.