{"record":{"id":"7637d1ba8cf76a74","repo":"vercel/turborepo","slug":"unable-to-fetch-the-latest-version-of-packagenam","errorCode":null,"errorMessage":"Unable to fetch the latest version of ${packageName}","messagePattern":"Unable to fetch the latest version of (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/turbo-codemod/src/commands/migrate/steps/get-latest-version.ts","lineNumber":24,"sourceCode":"  \"dist-tags\": {\n    latest: string;\n    [key: string]: string;\n  };\n  versions: Record<string, { name: string; version: string }>;\n}\n\nasync function getPackageDetails({ packageName }: { packageName: string }) {\n  const registry =\n    process.env.npm_config_registry?.replace(/\\/$/, \"\") || DEFAULT_REGISTRY;\n\n  try {\n    const response = await fetch(`${registry}/${packageName}`);\n    if (!response.ok) {\n      throw new Error(`HTTP ${response.status}`);\n    }\n    return (await response.json()) as PackageDetailsResponse;\n  } catch (err) {\n    throw new Error(`Unable to fetch the latest version of ${packageName}`);\n  }\n}\n\nexport async function getLatestVersion({\n  to\n}: MigrateCommandOptions): Promise<string | undefined> {\n  const packageDetails = await getPackageDetails({ packageName: \"turbo\" });\n  const { \"dist-tags\": tags, versions } = packageDetails;\n\n  if (to) {\n    // If 'to' is a dist-tag (e.g. \"latest\", \"canary\"), resolve to the concrete version\n    if (tags[to]) {\n      return tags[to];\n    }\n    if (to in versions) {\n      return to;\n    }\n    throw new Error(`turbo@${to} does not exist`);","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/vercel/turborepo/blob/9f94a7d215b3881942527dd526afa3fc650869d5/packages/turbo-codemod/src/commands/migrate/steps/get-latest-version.ts#L6-L42","documentation":"`turbo-codemod migrate` resolves the target turbo version by fetching package metadata from the npm registry (`${registry}/turbo`, where registry comes from npm_config_registry or defaults to registry.npmjs.org). Any failure — network error, DNS failure, or non-2xx HTTP status — is wrapped in this Error. Note the fetch happens before the `--to` check, so even an explicit `--to <version>` requires registry access.","triggerScenarios":"getPackageDetails' fetch throwing or returning !response.ok: offline machine, corporate proxy/firewall blocking registry.npmjs.org, npm_config_registry pointing at a private registry (Artifactory/Verdaccio) that lacks the `turbo` package metadata, or a registry 5xx/404.","commonSituations":"Air-gapped or proxied CI environments; private registries that don't proxy npmjs; HTTP__PROXY/HTTPS_PROXY env vars not visible to the codemod process; transient registry outages.","solutions":["Verify registry connectivity the same way the codemod does: `npm view turbo version` from the same shell","If npm_config_registry points at a private registry, ensure it proxies the npmjs group (including the `turbo` package) or override it for the run: `npm_config_registry=https://registry.npmjs.org npx @turbo/codemod migrate`","Configure proxy env vars (HTTPS_PROXY/HTTP_PROXY) so fetch can traverse the corporate proxy, then retry","On flaky networks, simply retry the codemod — it is idempotent with respect to the registry query"],"exampleFix":"# before\nnpx @turbo/codemod migrate   # fails behind private registry\n# after\nnpm_config_registry=https://registry.npmjs.org npx @turbo/codemod migrate","handlingStrategy":"retry","validationCode":"async function registryServesTurbo(registry = process.env.npm_config_registry ?? 'https://registry.npmjs.org'): Promise<boolean> {\n  try {\n    const res = await fetch(`${registry.replace(/\\/$/, '')}/turbo`, { method: 'GET' });\n    return res.ok;\n  } catch {\n    return false;\n  }\n}\n// run before turbo-codemod migrate; if false, fix registry/proxy first","typeGuard":null,"tryCatchPattern":"async function migrateWithRetry(opts, attempts = 3) {\n  for (let i = 0; i < attempts; i++) {\n    try {\n      return await runMigrate(opts);\n    } catch (err) {\n      if (err instanceof Error && /Unable to fetch the latest version/.test(err.message) && i < attempts - 1) {\n        await new Promise((r) => setTimeout(r, 2 ** i * 500)); // backoff, then retry\n        continue;\n      }\n      throw err;\n    }\n  }\n}","preventionTips":["Run `npm view turbo version` in CI before the codemod to prove registry reachability with the same env","Ensure private registries (Artifactory/Verdaccio) proxy the npmjs remote that carries `turbo`","Export HTTPS_PROXY/HTTP_PROXY in the codemod's environment when behind a corporate proxy","Remember: `--to <exact-version>` does not bypass the fetch — the codemod always queries the registry"],"tags":["turbo-codemod","network","npm-registry","migrate","proxy"],"backgroundTag":"npm-registry-unreachable","analyzedSha":"9f94a7d215b3881942527dd526afa3fc650869d5","analyzedAt":"2026-08-16T19:47:29.531Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}