can1357/oh-my-pi · error · Error
Failed to download: ${response.status}
Error message
Failed to download: ${response.status} What it means
downloadFile() fetches the release asset URL and validates response.ok before streaming the body to disk. Any non-2xx download response (asset removed, bad URL, redirect failure) is rejected with this error, which includes the HTTP status code to identify the cause.
Source
Thrown at packages/coding-agent/src/utils/tools-manager.ts:204
if (!response.ok) {
throw new Error(`GitHub API error: ${response.status}`);
}
const data = (await response.json()) as { tag_name: string };
return data.tag_name.replace(/^v/, "");
}
/** Download a tool asset without handing the streaming Response to Bun.write. */
export async function downloadFile(url: string, dest: string, signal?: AbortSignal): Promise<void> {
const downloadSignal = ptree.combineSignals(signal, TOOL_DOWNLOAD_TIMEOUT_MS);
let response: Response;
try {
response = await fetch(url, {
signal: downloadSignal,
});
if (!response.ok) {
throw new Error(`Failed to download: ${response.status}`);
} else if (!response.body) {
throw new Error("No response body");
}
await writeResponseBody(dest, response.body, downloadSignal);
} catch (err) {
if (isAbortLikeError(err)) {
throw new Error(`Download timed out: ${url}`);
}
throw err;
}
}
// Download and install a tool
async function downloadTool(tool: ToolName, signal?: AbortSignal): Promise<string> {
const config = TOOLS[tool];
if (!config) throw new Error(`Unknown tool: ${tool}`);
const plat = os.platform();View on GitHub (pinned to 9690622007)
Solutions
- Check the status: 404 → the asset URL is wrong or the asset was removed for this release; 403 → throttling; 5xx → transient.
- Construct the asset URL and open it in a browser to confirm the asset exists for that version.
- If a fresh release has missing assets, retry later once the maintainer finishes uploading, or pin to an earlier complete release.
- Verify the getAssetName logic / platform mapping matches the upstream naming scheme for the failing platform.
- Retry the download; transient 5xx usually resolves.
Example fix
// before: const binaryPath = await toolsManager.download("sg") // throws "Failed to download: 404" | // after: catch, and if /Failed to download: 404/ matches, fall back to system-installed binary; rethrow otherwise Defensive patterns
Strategy: fallback
Validate before calling
// verify the asset URL exists before invoking the download path | const head = await fetch(assetUrl, { method: "HEAD" }); if (!head.ok) throw new Error(`Asset missing: ${assetUrl} (${head.status})`); Type guard
function isDownloadHttpError(err: unknown): err is Error { return err instanceof Error && /^Failed to download: \d+$/.test(err.message); } Try / catch
try { const p = await toolsManager.path("fd"); } catch (err) { if (isDownloadHttpError(err) && err.message.endsWith("404")) { /* fall back to system-installed binary */ } else throw err; } Prevention
- Keep the manager's asset-name mapping in sync with upstream release naming.
- Prefer an existing system binary when available instead of always downloading.
- Retry once for 5xx; don't retry 404.
- Pin tool versions when upstream is actively releasing.
When it happens
Trigger: downloadTool fetches the constructed release asset URL https://github.com/<repo>/releases/download/<tagPrefix><version>/<assetName> and GitHub responds with a non-OK status — typically 404 when the asset name for the current version/platform does not exist, or 403/5xx from GitHub-side issues.
Common situations: Upstream release renamed or dropped the asset for your OS/arch, a brand-new release where assets are still uploading, tagPrefix mismatch producing a malformed URL, or GitHub returning 403 on throttled direct downloads.
Related errors
- Download failed: ${response.statusText}
- Devin API error ${response.status} ${response.statusText}: $
- Failed to initiate device authorization: ${initiateResponse.
- Failed to download the local text-to-speech model.
- One or more tiny title models failed to download
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/5e141d344ea2642a.
Report an issue: GitHub.