vercel/turborepo · error · Error
Unable to fetch the latest version of ${packageName}
Error message
Unable to fetch the latest version of ${packageName} What it means
`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.
Source
Thrown at packages/turbo-codemod/src/commands/migrate/steps/get-latest-version.ts:24
"dist-tags": {
latest: string;
[key: string]: string;
};
versions: Record<string, { name: string; version: string }>;
}
async function getPackageDetails({ packageName }: { packageName: string }) {
const registry =
process.env.npm_config_registry?.replace(/\/$/, "") || DEFAULT_REGISTRY;
try {
const response = await fetch(`${registry}/${packageName}`);
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
return (await response.json()) as PackageDetailsResponse;
} catch (err) {
throw new Error(`Unable to fetch the latest version of ${packageName}`);
}
}
export async function getLatestVersion({
to
}: MigrateCommandOptions): Promise<string | undefined> {
const packageDetails = await getPackageDetails({ packageName: "turbo" });
const { "dist-tags": tags, versions } = packageDetails;
if (to) {
// If 'to' is a dist-tag (e.g. "latest", "canary"), resolve to the concrete version
if (tags[to]) {
return tags[to];
}
if (to in versions) {
return to;
}
throw new Error(`turbo@${to} does not exist`);View on GitHub (pinned to 9f94a7d215)
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
Example fix
# before npx @turbo/codemod migrate # fails behind private registry # after npm_config_registry=https://registry.npmjs.org npx @turbo/codemod migrate
Defensive patterns
Strategy: retry
Validate before calling
async function registryServesTurbo(registry = process.env.npm_config_registry ?? 'https://registry.npmjs.org'): Promise<boolean> {
try {
const res = await fetch(`${registry.replace(/\/$/, '')}/turbo`, { method: 'GET' });
return res.ok;
} catch {
return false;
}
}
// run before turbo-codemod migrate; if false, fix registry/proxy first Try / catch
async function migrateWithRetry(opts, attempts = 3) {
for (let i = 0; i < attempts; i++) {
try {
return await runMigrate(opts);
} catch (err) {
if (err instanceof Error && /Unable to fetch the latest version/.test(err.message) && i < attempts - 1) {
await new Promise((r) => setTimeout(r, 2 ** i * 500)); // backoff, then retry
continue;
}
throw err;
}
}
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- turbo@${to} does not exist
- Invalid version: ${version}
- isErrorLike(reason) ? reason.message : String(reason)
- Failed to download: ${response.status}
AI-assisted analysis of vercel/turborepo@9f94a7d215 (2026-08-16).
Data as JSON: /api/errors/7637d1ba8cf76a74.
Report an issue: GitHub.