{"record":{"id":"d7c71d9a30a6b343","repo":"can1357/oh-my-pi","slug":"fetching-oh-my-pi-pkg-version-failed-http","errorCode":null,"errorMessage":"Fetching @oh-my-pi/${pkg}@${version} failed: HTTP ${response.status}","messagePattern":"Fetching @oh-my-pi/(.+?)@(.+?) failed: HTTP (.+?)","errorType":"http","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/metaharness/src/tb/agent.ts","lineNumber":35,"sourceCode":"\tif (exitCode !== 0) throw new Error(`${command.join(\" \")} exited with code ${exitCode}`);\n}\n/**\n * Refresh cross-target `pi_natives.linux-<arch>*.node` files in\n * `packages/natives/native/` from the published npm leaf package.\n *\n * The binary build embeds whatever `.node` files sit in that directory; on a\n * non-linux host they are stale local cross-builds that can fail `dlopen`\n * inside task guests (undefined libstdc++ symbols). The matching published\n * leaf is the artifact real installs load, so it is the ground truth for\n * embedding; an unpublished working-tree version fails instead of risking\n * loader/API skew.\n */\nasync function refreshCrossNatives(arches: GuestArch[], version: string): Promise<void> {\n\tfor (const arch of arches) {\n\t\tif (process.platform === \"linux\" && process.arch === arch) continue;\n\t\tconst pkg = `pi-natives-linux-${arch}`;\n\t\tconst response = await fetch(`https://registry.npmjs.org/@oh-my-pi/${pkg}/-/${pkg}-${version}.tgz`);\n\t\tif (!response.ok) throw new Error(`Fetching @oh-my-pi/${pkg}@${version} failed: HTTP ${response.status}`);\n\t\tconst archive = new Bun.Archive(await response.arrayBuffer());\n\t\tlet extracted = 0;\n\t\tfor (const [entry, file] of await archive.files()) {\n\t\t\tconst name = path.posix.basename(entry);\n\t\t\tif (!name.startsWith(`pi_natives.linux-${arch}`) || !name.endsWith(\".node\")) continue;\n\t\t\tawait Bun.write(path.join(NATIVES_DIR, name), file);\n\t\t\textracted++;\n\t\t}\n\t\tif (extracted === 0) throw new Error(`@oh-my-pi/${pkg}@${version} tarball contained no .node files`);\n\t}\n}\n\n/** Build and cache self-contained omp binaries for the selected guest architectures. */\nexport async function prepareAgentBinaries(opts: {\n\tarches: GuestArch[];\n\tcacheDir: string;\n\trebuild: boolean;\n}): Promise<AgentBinaries> {","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/metaharness/src/tb/agent.ts#L17-L53","documentation":"refreshCrossNatives downloads the published `@oh-my-pi/pi-natives-linux-<arch>` tarball from the npm registry and throws this error when the HTTP response is not ok (404, 403, 5xx, etc.). It means the registry could not serve the tarball for the requested version.","triggerScenarios":"Calling prepareAgentBinaries with guest arches that need cross-native refresh at a `version` for which `https://registry.npmjs.org/@oh-my-pi/pi-natives-linux-<arch>/-/<pkg>-<version>.tgz` returns a non-2xx status — typically 404 because the version was never published for that package.","commonSituations":"Local/workspace version (e.g. 0.0.0-dev or a snapshot version) that was never published to npm; typo'd or brand-new version published only for some platforms; npm registry outage or proxy blocking; network offline.","solutions":["Check the tarball exists: open the registry URL in a browser or `npm view @oh-my-pi/pi-natives-linux-x64 versions`","Publish the missing version of the platform package (or run the publish step) before cross-refresh","Use a version that is actually published on npm","Check network/proxy/VPN and npm registry status if the package is known to exist"],"exampleFix":"// before\nawait prepareAgentBinaries({ arches: [\"arm64\"], cacheDir, rebuild: true }); // uses unreleased local version\n// after — guard against unpublished versions\nconst { version } = await Bun.file(path.join(CODING_AGENT_DIR, \"package.json\")).json();\nif (version.includes(\"-\") || version === \"0.0.0\") throw new Error(`version ${version} not published; commit a released version`);","handlingStrategy":"retry","validationCode":"async function tarballExists(pkg: string, version: string): Promise<boolean> {\n  const res = await fetch(`https://registry.npmjs.org/@oh-my-pi/${pkg}/${version}`);\n  return res.ok;\n}","typeGuard":null,"tryCatchPattern":"try {\n  await refreshCrossNatives(arches, version);\n} catch (err) {\n  if (err instanceof Error && err.message.includes(\"failed: HTTP 404\")) {\n    throw new Error(`version ${version} not published to npm; publish or pick a released version`);\n  }\n  if (err instanceof Error && /failed: HTTP 5\\d\\d/.test(err.message)) {\n    await Bun.sleep(2000); // transient registry error: retry once\n    await refreshCrossNatives(arches, version);\n  } else throw err;\n}","preventionTips":["Only cross-refresh against versions actually published to npm","Check `npm view @oh-my-pi/pi-natives-linux-<arch> versions` first","Retry transient 5xx with backoff","Verify network/proxy access to registry.npmjs.org"],"tags":["network","npm","fetch"],"backgroundTag":"npm-tarball-not-found","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}