{"record":{"id":"82839b5f659bcc0a","repo":"shadcn-ui/ui","slug":"gone","errorCode":"GONE","errorMessage":"The item at ${url} is no longer available. It may have been removed or expired.","messagePattern":"The item at (.+?) is no longer available\\. It may have been removed or expired\\.","errorType":"http","errorClass":"RegistryGoneError","httpStatus":410,"severity":"error","filePath":"packages/shadcn/src/registry/fetcher.ts","lineNumber":99,"sourceCode":"                // Prefer RFC 7807 detail field, then message field.\n                messageFromServer = parsed.data.detail || parsed.data.message\n\n                if (parsed.data.error) {\n                  messageFromServer = `[${parsed.data.error}] ${messageFromServer}`\n                }\n              }\n            }\n\n            if (response.status === 401) {\n              throw new RegistryUnauthorizedError(url, messageFromServer)\n            }\n\n            if (response.status === 404) {\n              throw new RegistryNotFoundError(url, messageFromServer)\n            }\n\n            if (response.status === 410) {\n              throw new RegistryGoneError(url, messageFromServer)\n            }\n\n            if (response.status === 403) {\n              throw new RegistryForbiddenError(url, messageFromServer)\n            }\n\n            throw new RegistryFetchError(\n              url,\n              response.status,\n              messageFromServer\n            )\n          }\n\n          return response.json()\n        })()\n\n        if (options.useCache) {\n          registryCache.set(cacheKey, fetchPromise)","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/shadcn-ui/ui/blob/efac5987074af84ece57c367c6dd83387b967022/packages/shadcn/src/registry/fetcher.ts#L81-L117","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nnpx shadcn add @myorg/button@v1  // returns 410\n\n// after\nnpx shadcn add @myorg/button@v2","handlingStrategy":"try-catch","validationCode":"// 410 is terminal; validate availability from a catalog listing before fetch.\nasync function assertItemNotGone(registryUrl: string, itemName: string) {\n  const [catalog] = await fetchRegistry([registryUrl]);\n  const exists = catalog.items?.some((i: { name: string }) => i.name === itemName);\n  if (!exists) throw new Error(`${itemName} is not in the catalog (possibly gone).`);\n}","typeGuard":"function isGoneError(err: unknown): boolean {\n  return err instanceof RegistryGoneError;\n}","tryCatchPattern":"try {\n  await fetchRegistry([url]);\n} catch (err) {\n  if (err instanceof RegistryGoneError) {\n    // do NOT retry; surface migration guidance from the registry changelog\n  }\n  throw err;\n}","preventionTips":["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."],"tags":["network","gone","registry","deprecation","typescript"],"backgroundTag":null,"analyzedSha":"efac5987074af84ece57c367c6dd83387b967022","analyzedAt":"2026-08-12T05:00:50.218Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}