shadcn-ui/ui · error · RegistryNotFoundError
NOT_FOUND
NOT_FOUND
Error message
The item at ${url} was not found. It may not exist at the registry. What it means
Thrown by fetchRegistry when the registry endpoint responds with HTTP 404. RegistryNotFoundError means the requested item or catalog URL does not exist at the registry. The URL that 404'd is included; the server's message is attached as cause when available.
Source
Thrown at packages/shadcn/src/registry/fetcher.ts:95
})
.safeParse(json)
if (parsed.success) {
// 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()View on GitHub (pinned to efac598707)
Solutions
- Verify the exact item name against the registry's published catalog.
- Open the failing URL in a browser to confirm the 404.
- Check the registry URL template and the {name} placeholder spelling.
- If the item was renamed, update the reference to the new name.
Example fix
// before npx shadcn add @myorg/old-button-name // after (after checking the catalog) npx shadcn add @myorg/button
Defensive patterns
Strategy: validation
Validate before calling
async function catalogHasItem(registryUrl: string, itemName: string) {
const [catalog] = await fetchRegistry([registryUrl]);
return Array.isArray(catalog.items) && catalog.items.some(i => i.name === itemName);
}
// check before fetching the item directly Type guard
function itemExistsInCatalog(catalog: { items?: { name: string }[] }, name: string): boolean {
return Array.isArray(catalog.items) && catalog.items.some(i => i.name === name);
} Try / catch
try {
await fetchRegistry([url]);
} catch (err) {
if (err instanceof RegistryNotFoundError) {
// fetch the catalog and suggest the closest matching item name
}
throw err;
} Prevention
- List the catalog first and pick item names from the returned list.
- Keep the {name} placeholder in registry URL templates to avoid path drift.
- Pin registry versions to avoid upstream removals.
When it happens
Trigger: Requesting an item name that the registry does not serve (typo or removed), pointing at a registry URL whose path is wrong, or fetching an item from a registry that only exposes a catalog. Also when an upstream registry retires an item.
Common situations: Item renamed or removed upstream, wrong registry base URL, missing '{name}' placeholder substitution, or a private registry that returns 404 instead of 401 for unauthenticated requests.
Related errors
AI-assisted analysis of shadcn-ui/ui@efac598707 (2026-08-12).
Data as JSON: /api/errors/f2a9eb573f810d83.
Report an issue: GitHub.