{"record":{"id":"cec03811517a130b","repo":"shadcn-ui/ui","slug":"failed-to-resolve-github-ref-ref-for-addres","errorCode":null,"errorMessage":"Failed to resolve GitHub ref \"${ref}\" for ${address.owner}/${address.repo}. ${guidance.detail}","messagePattern":"Failed to resolve GitHub ref \"(.+?)\" for (.+?)/(.+?)\\. (.+?)","errorType":"exception","errorClass":"RegistrySourceFileError","httpStatus":null,"severity":"error","filePath":"packages/shadcn/src/registry/github-ref.ts","lineNumber":193,"sourceCode":"      throw refError\n    }\n\n    const guidance = getGitHubTransportFailureGuidance(error, mode)\n\n    // A missing gh binary or missing credentials keeps the original message\n    // and adds setup guidance.\n    if (error.kind === \"enoent\" || error.kind === \"unauthenticated\") {\n      throw new RegistrySourceFileError(\"registry.json\", undefined, {\n        message: refError.message,\n        context: {\n          reason: \"github-ref-resolution\",\n          source: formatGitHubSource(address),\n          ref,\n        },\n        suggestion: guidance.suggestion,\n      })\n    }\n    throw new RegistrySourceFileError(\"registry.json\", undefined, {\n      message: `Failed to resolve GitHub ref \"${ref}\" for ${address.owner}/${address.repo}. ${guidance.detail}`,\n      context: {\n        reason: \"github-ref-resolution\",\n        source: formatGitHubSource(address),\n        ref,\n      },\n      suggestion: guidance.suggestion,\n    })\n  }\n}\n\nfunction createGitHubRefResolutionError(\n  address: GitHubSource,\n  ref: string,\n  repoUrl: string,\n  error: unknown\n) {\n  return new RegistrySourceFileError(\"registry.json\", error, {","sourceCodeStart":175,"sourceCodeEnd":211,"githubUrl":"https://github.com/shadcn-ui/ui/blob/683a5a9b370acdb7785a0529434e6a3b8c7e0441/packages/shadcn/src/registry/github-ref.ts#L175-L211","documentation":"This error means ref resolution reached an authenticated GitHub transport (gh CLI or REST API with a token) but the request failed for a transport-level reason other than 404, missing gh, or missing credentials — e.g. HTTP 401/403/429/5xx, timeouts, or network failures. The message includes the ref, the owner/repo, and a guidance detail produced by getGitHubTransportFailureGuidance (rate-limit, permission, or network advice). It wraps the failure in a RegistrySourceFileError with reason 'github-ref-resolution'.","triggerScenarios":"Calling a registry add/fetch that resolves a GitHub ref where the authenticated transport throws a GitHubTransportError whose kind is not 'enoent' or 'unauthenticated' and not an HTTP 404: rate limiting (HTTP 429), bad/expired token (401), SAML/organization blocking (403), GitHub 5xx outages, proxy/DNS/network failures, or timeouts while running `gh` or hitting the GitHub API for owner/repo at the given ref.","commonSituations":"Unauthenticated or low-rate-limit requests hitting GitHub API rate limits in CI; expired PAT used as GH_TOKEN; private repos in orgs requiring SSO authorization; corporate proxies or firewalls blocking api.github.com; GitHub incidents; too many parallel ref resolutions in monorepo builds.","solutions":["Check guidance.detail and the error context: for 429 rate limits, wait or add a token (gh auth login / GH_TOKEN) to raise the limit","Run `gh auth status` to confirm the token is valid, not expired, and authorized for the org (SSO) if the repo is private","Retry after a short backoff — transient 5xx and network blips usually resolve; check https://www.githubstatus.com during incidents","Verify the network path to api.github.com (proxy, HTTPS_PROXY, DNS, firewall) from the environment running the CLI","Confirm the ref actually exists on the remote (`git ls-remote https://github.com/owner/repo`) to rule out ref problems surfacing as transport errors"],"exampleFix":"# before\nGH_TOKEN=expired-token npx shadcn add owner/repo\n# -> Failed to resolve GitHub ref \"main\" for owner/repo. ... 401 ...\n\n# after\nexport GH_TOKEN=$(gh auth token)  # fresh valid token\nnpx shadcn add owner/repo","handlingStrategy":"retry","validationCode":"async function githubReachable(): Promise<boolean> {\n  try {\n    const res = await fetch(\"https://api.github.com/rate_limit\", {\n      headers: process.env.GH_TOKEN ? { Authorization: `Bearer ${process.env.GH_TOKEN}` } : {},\n    })\n    return res.ok || res.status === 403 || res.status === 429 // still reachable\n  } catch { return false }\n}\n// before resolving many refs, verify reachability and token validity","typeGuard":"function isRegistrySourceFileError(e: unknown): e is RegistrySourceFileError {\n  return e instanceof RegistrySourceFileError\n}\nfunction isGitHubRefResolutionFailure(e: unknown): boolean {\n  return (\n    isRegistrySourceFileError(e) &&\n    (e.context as any)?.reason === \"github-ref-resolution\"\n  )\n}","tryCatchPattern":"async function withRetry<T>(fn: () => Promise<T>, attempts = 3): Promise<T> {\n  for (let i = 0; i < attempts; i++) {\n    try {\n      return await fn()\n    } catch (error) {\n      if (isGitHubRefResolutionFailure(error) && /rate limit|5xx|timeout|ETIMEDOUT/i.test(error.message)) {\n        await new Promise(r => setTimeout(r, 2 ** i * 1000))\n        continue\n      }\n      throw error\n    }\n  }\n  throw new Error(\"GitHub ref resolution failed after retries\")\n}","preventionTips":["Always set a valid GH_TOKEN in CI to get higher API rate limits","Back off and retry on 429/5xx; do not retry 401/403 (fix the token/SSO instead)","Keep tokens fresh and SSO-authorize them for private orgs","Limit parallel registry resolutions to avoid burst rate limiting","Monitor githubstatus.com in CI failure triage"],"tags":["github","rate-limit","network","authentication","registry","api"],"backgroundTag":"github-api-request-failed","analyzedSha":"683a5a9b370acdb7785a0529434e6a3b8c7e0441","analyzedAt":"2026-08-27T14:12:43.753Z","contentChangedAt":"2026-08-27T14:12:43.753Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}