shadcn-ui/ui · error · RegistryUnauthorizedError

UNAUTHORIZED

UNAUTHORIZED

Error message

You are not authorized to access the item at ${url}. If this is a remote registry, you may need to authenticate.

What it means

Thrown by fetchRegistry when the registry endpoint responds with HTTP 401. RegistryUnauthorizedError signals that authentication is required and was not provided (or was invalid). The server's RFC 7807 detail/message, if any, is captured as the cause for display.

Source

Thrown at packages/shadcn/src/registry/fetcher.ts:91

                  title: z.string().optional(),
                  // Standard error response.
                  message: z.string().optional(),
                  error: z.string().optional(),
                })
                .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

View on GitHub (pinned to efac598707)

Solutions

  1. Configure the registry's auth header in components.json: "@myorg": { "url": "...", "headers": { "Authorization": "Bearer ${REGISTRY_TOKEN}" } }.
  2. Export the referenced env var (e.g. REGISTRY_TOKEN) in your shell or .env.
  3. Confirm the token is still valid and has not expired.
  4. If the registry uses a different scheme (basic, cookie), set the matching header.

Example fix

// before: components.json
{
  "registries": {
    "@myorg": "https://priv.example.com/r/{name}.json"
  }
}

// after
{
  "registries": {
    "@myorg": {
      "url": "https://priv.example.com/r/{name}.json",
      "headers": { "Authorization": "Bearer ${REGISTRY_TOKEN}" }
    }
  }
}
Defensive patterns

Strategy: validation

Validate before calling

function ensureAuthHeaders(registryConfig: { headers?: Record<string,string> }, requiredVars: string[]) {
  for (const v of requiredVars) {
    if (!process.env[v]) {
      throw new Error(`Missing env var ${v} required for registry auth.`);
    }
  }
  return registryConfig;
}

Type guard

function hasAuthHeader(headers?: Record<string,string>): boolean {
  if (!headers) return false;
  const keys = Object.keys(headers).map(k => k.toLowerCase());
  return keys.includes("authorization") || keys.includes("cookie") || keys.includes("x-api-key");
}

Try / catch

try {
  await fetchRegistry([url]);
} catch (err) {
  if (err instanceof RegistryUnauthorizedError) {
    // prompt user to set REGISTRY_TOKEN, then retry once
  }
  throw err;
}

Prevention

When it happens

Trigger: Fetching an item or catalog from a private/authenticated registry without sending the required Authorization header, with an expired token, or with credentials for the wrong account.

Common situations: Custom registry requires a bearer token but the header was not configured in components.json, an env var referenced by the header is unset/empty, or the token was revoked.

Understand the failure class

Related errors


AI-assisted analysis of shadcn-ui/ui@efac598707 (2026-08-12). Data as JSON: /api/errors/c916846d052dd3e2. Report an issue: GitHub.