squirrelscan
GitHub

An Organization on one page, a LocalBusiness on another

The same @id declared with different @type sets on different pages. A search engine merges them and then has to decide which types are authoritative.

What drifts, and why it matters

A contact page that upgrades the organization to a LocalBusiness while every other page leaves it as an Organization is the usual shape. Someone added the address and the opening hours where they were relevant, which is a reasonable instinct and the wrong place to act on it.

Types drive eligibility. A LocalBusiness can earn a local pack listing and opening-hours display; an Organization cannot. The two declarations are compatible and a consumer may well accumulate both, as the entity map itself does. What you lose is the certainty: whether the pages that say only Organization are read as complete, and whether a consumer sampling one of them sees a business at all.

One type set, on every declaration.

What squirrel checks

The rule runs once per crawl, reads the entity map rather than the pages, and emits a single check named entity-type-drift.

  • Skipped with the message No entity map was built for this audit and the reason entity-map-unavailable when the run produced no map. This is not the same as a site with no structured data, and the rule refuses to conflate them: passing here would assert it had checked something it never looked at.
  • Reports at info with the message This site declares no JSON-LD entities on any crawled page when the map exists and is empty.
  • Passes with the message Every @id carries the same @type set on every page.
  • Warns with the message N entities are declared with more than one @type set, plus (+N more entities) when more matched than are listed. The value reads NAME: TYPES vs TYPES and the expectation is one @type set per @id.

Type sets are compared after deduplicating and sorting, so ["Organization","LocalBusiness"] and ["LocalBusiness","Organization"] are the same set. schema.org puts no meaning on the order and neither does this check.

Only entities with an @id are judged. An entity without one has no identity for its types to drift against; whether it is reported at all is schema/entity-identity’s question, and that rule looks only at named, multi-page entities of four specific types.

Findings are capped at 10 items, and the count in the message is always the true total rather than the capped length. Run squirrel entities -f json and read the entities key for the full list.

How to fix it

Decide what the entity is and say it the same way everywhere. If it is a local business, declare it as one on every page, not only where the address appears:

{
  "@type": ["Organization", "LocalBusiness"],
  "@id": "https://example.com/#organization",
  "name": "Example Ltd"
}

The properties can still vary by page, and usually should: put the address and hours where they belong. It is the type array that has to be constant. See fixing structured data identity.

Rule IDschema/entity-type-drift
CategoryStructured Data
ScopeSite-wide
Severitywarning
Weight3/10

Enable / disable

Disable this rule

[rules]
disable = ["schema/entity-type-drift"]

Disable all Structured Data rules

[rules]
disable = ["schema/*"]

Enable only this rule

[rules]
enable = ["schema/entity-type-drift"]

enable replaces the default ["*"], so this is the only rule selected. Leave disable out: a rule that matches any disable pattern is skipped even when enable names it. Only an enabled setting under a rule’s own [rule_options] table overrides both lists.

Entity findings are site-wide and ship in every audit, next to the per-page structured data rules. See Fix SEO issues with AI for how an agent works through a report.

References

Check your site

Run squirrel audit https://example.com, then squirrel entities to see the graph the finding came from. Signed-out local audits need no account and cost nothing. Signed-in audits spend credits.

Type to search…

↑↓ navigate↵ openesc close