Docket / Fix it / Schema references

An @id is a pointer, not a definition

An audit reports that several of your pages have incomplete Organization markup. You open one and the Organization is right there — name, URL, logo, all of it. The blocks the tool is complaining about are not incomplete entities. They are references to that one.

What an @id actually does

In JSON-LD, two nodes that share an @id are one node. That is the whole point of the identifier, and it is what makes the common @graph pattern work: define your company once, then point at it from everywhere else.

The pointer looks like this, and it is complete as written:

"publisher": {
  "@type": "Organization",
  "@id": "https://example.com/#organization"
}

It carries no properties by design. Nobody forgot anything. And because this is what the most widely used SEO plugins and CMS platforms emit by default, a check that reads each stub as its own half-finished entity will fire on an enormous share of the web — including sites whose structured data is exactly right.

The false positive, reproduced on purpose

This one was not found on somebody's site and guessed at. It was reproduced with a controlled input: a graph that defines an Organization with name, URL and logo, and also references it by a typed @id. The result was a finding across several pages saying the Organization markup was incomplete. Nothing was incomplete. The reference was being counted as a second, worse copy of the thing it pointed at.

If your report says this about a site using a mainstream plugin, check the graph before you touch anything. The stub is not the error; reading it as a definition is.

The real problem underneath, with the opposite fix

Here is why this is worth more than "your tool was wrong". There is a genuine defect that looks identical from the outside, and it is common.

Structured data is read one page at a time. A search engine parsing your product page does not go and fetch your homepage to resolve an identifier. So if every block of a type on a page is a bare @id reference, and nothing on that page says what the identifier refers to, the reference resolves to nothing.

And "add the missing properties" is precisely the wrong instruction, because it misdescribes what happened. Nobody forgot a property. Somebody wrote a reference, deliberately, believing the definition exists somewhere — which it may well do, on a different page, where it cannot help. Telling them to add a name to each stub asks them to duplicate a definition they think they already have.

The two repairs that are actually available:

Why nothing catches this

A dangling @id produces neither a rich result nor an error, which is the most useful sentence on this page.

It is a failure of resolution, not of syntax, and syntax is what most tooling checks.

What a tool can honestly say about it

Worth stating because it bounds the finding. A crawler reads each page's markup on its own, exactly as a search engine does. So it can tell you the target is absent here. It cannot tell you the target is absent everywhere, because it is not resolving your graph across your whole site — and neither is the search engine, which is the entire reason this matters.

Checking your own markup in five minutes

When this does not matter

Two cases where a bare reference is fine as it stands:

The fixes that make it worse

How to clear this finding without improving anything

Delete the reference blocks. The finding goes away, and so does any chance of the entity being understood — you have removed the evidence of an intention rather than completing it. Worth knowing, because "it went green" and "it got better" are different outcomes and only one of them is visible in a report.

Where this sits in an audit

The registered check is schema.incomplete, which covers incomplete structured data in the structured data area. For the other ways JSON-LD goes wrong — blocks that do not parse, markup contradicting the visible page, required properties genuinely missing — see how to fix structured data errors →.

And for the general habit this page is an instance of — a finding whose own advice does not fit the case it fired on — see a caveat is not a gate →.

Common questions

What does @id mean in JSON-LD?

It identifies a node. Two blocks sharing an @id are the same node, which is what lets you define an entity once and reference it from elsewhere in the same document.

My audit says my Organization markup is incomplete but it looks fine. Why?

Probably because the blocks it flagged are @id references to a definition elsewhere in the graph. A reference carries no properties by design, and a tool reading it as its own entity will call it incomplete.

Can an @id point at a definition on another page?

No, not usefully. Structured data is read one page at a time, so a reference to a node defined on a different page resolves to nothing on the page that carries the reference.

Why does no validator catch a dangling @id?

Because it is valid JSON-LD. Validators check syntax; this is a failure of resolution. A rich-results test reports that nothing was found, which reads like missing markup rather than a pointer to nowhere.

Should I add the missing properties to each reference block?

No. That duplicates a definition rather than fixing one. Either define the entity on each page that references it, or remove the stub — as it stands it produces neither a rich result nor an error.