Error - Invalid Key: The GraphQL Query at the Field at Route:X
This warning is coming from urql's graphcache (a GraphQL caching library), not from Sanity itself. The issue is that graphcache needs a way to uniquely identify entities in its cache, and it's seeing your slug field as an object (selection set) without a unique identifier.
In Sanity, the slug type is indeed an object with a current property (like { current: "my-page" }), not a simple string. This is why GraphQL sees it as a selection set. And you're correct - the slug object itself doesn't have an _id field because it's not a document, it's just a field type.
Here are your solutions:
Solution 1: Configure urql graphcache to not cache slug objects (Recommended)
Add a custom keys config to tell graphcache that Slug objects shouldn't be cached separately:
import { cacheExchange } from '@urql/exchange-graphcache';
const cache = cacheExchange({
keys: {
Slug: () => null, // Tell graphcache not to cache Slug as a separate entity
}
});This tells graphcache to embed the slug data directly on the parent entity (your Route document), which is exactly what you want since slug is just a field, not a standalone entity.
Solution 2: Request _id on the parent Route document
Make sure you're requesting _id on your main Route document:
query {
allRoute {
_id
slug {
current
}
}
}This ensures the parent entity can be properly cached, though you'll still want Solution 1 for the Slug object itself.
Solution 3: Configure keys for all Sanity object types
If you have other Sanity object types (not documents) causing similar warnings, you can configure them all at once:
const cache = cacheExchange({
keys: {
Slug: () => null,
Geopoint: () => null,
Block: () => null,
Span: () => null,
// Add any other object types you use
}
});The first solution is what you need - Sanity's slug type is an embedded object, not a keyable entity, so telling urql to treat it as such resolves the warning correctly.
Sanity – Build the way you think, not the way your CMS thinks
Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.