shadcn-ui/ui · error · RegistryGoneError
GONE
GONE
Error message
The item at ${url} is no longer available. It may have been removed or expired. What it means
Thrown by fetchRegistry when the registry endpoint responds with HTTP 410 Gone. RegistryGoneError indicates the resource was deliberately removed and the endpoint is signalling permanence, distinguishing it from a transient 404.
Source
Thrown at packages/shadcn/src/registry/fetcher.ts:99
// Prefer RFC 7807 detail field, then message field.
messageFromServer = parsed.data.detail || parsed.data.message
if (parsed.data.error) {
messageFromServer = `[${parsed.data.error}] ${messageFromServer}`
}
}
}
if (response.status === 401) {
throw new RegistryUnauthorizedError(url, messageFromServer)
}
if (response.status === 404) {
throw new RegistryNotFoundError(url, messageFromServer)
}
if (response.status === 410) {
throw new RegistryGoneError(url, messageFromServer)
}
if (response.status === 403) {
throw new RegistryForbiddenError(url, messageFromServer)
}
throw new RegistryFetchError(
url,
response.status,
messageFromServer
)
}
return response.json()
})()
if (options.useCache) {
registryCache.set(cacheKey, fetchPromise)View on GitHub (pinned to efac598707)
Solutions
- Migrate to the replacement item/version indicated by the registry's changelog.
- Pin to a registry version/tag that still serves the item.
- Contact the registry maintainer if no replacement is documented.
- If you control the registry, ensure a documented migration path exists before returning 410.
Example fix
// before npx shadcn add @myorg/button@v1 // returns 410 // after npx shadcn add @myorg/button@v2
Defensive patterns
Strategy: try-catch
Validate before calling
// 410 is terminal; validate availability from a catalog listing before fetch.
async function assertItemNotGone(registryUrl: string, itemName: string) {
const [catalog] = await fetchRegistry([registryUrl]);
const exists = catalog.items?.some((i: { name: string }) => i.name === itemName);
if (!exists) throw new Error(`${itemName} is not in the catalog (possibly gone).`);
} Type guard
function isGoneError(err: unknown): boolean {
return err instanceof RegistryGoneError;
} Try / catch
try {
await fetchRegistry([url]);
} catch (err) {
if (err instanceof RegistryGoneError) {
// do NOT retry; surface migration guidance from the registry changelog
}
throw err;
} Prevention
- Treat 410 as permanent: do not retry the same ref.
- Subscribe to registry changelogs to learn about deprecations in advance.
- Pin to specific versions rather than floating tags to avoid sudden removals.
When it happens
Trigger: An item or catalog endpoint that was deprecated and explicitly returns 410, or a registry that prunes old versions and marks removed items as gone rather than missing.
Common situations: Upstream registry versioning policy removes an old major version of an item and serves 410 to force migration. A registry sunsets a namespace and signals it via 410.
Related errors
AI-assisted analysis of shadcn-ui/ui@efac598707 (2026-08-12).
Data as JSON: /api/errors/82839b5f659bcc0a.
Report an issue: GitHub.