can1357/oh-my-pi · error
${destination} upload failed with HTTP ${status}
Error message
${destination} upload failed with HTTP ${status} What it means
expectOk checks an HTTP response and throws a secret-safe error containing only the destination name and status code when the response is not ok. Response bodies are intentionally excluded because they could echo back credentials, file contents, or signed URLs. Any non-2xx from an upload/list/session/permission endpoint surfaces as this error.
Source
Thrown at packages/coding-agent/src/blob-broker/uploader-runtime.ts:121
/** Build a native multipart form containing string fields and the uploaded file. */
export function multipartFile(
request: BlobUploadRequest,
fieldName = "file",
fields: Readonly<Record<string, string>> = {},
): FormData {
const form = new FormData();
for (const key in fields) form.append(key, fields[key]);
const file = new File([request.bytes], fileNameFor(request), { type: request.mimeType });
form.append(fieldName, file);
return form;
}
/** Return a successful response or throw a secret-safe HTTP status error. */
export async function expectOk(response: Response, destination: BlobDestinationId | string): Promise<Response> {
if (!response.ok) {
const status = response.statusText ? `${response.status} ${response.statusText}` : String(response.status);
throw new Error(`${destination} upload failed with HTTP ${status}`);
}
return response;
}
/** Construct a durable publication while preserving all upstream metadata. */
export function publication(
destination: BlobDestinationId,
request: BlobUploadRequest,
url: string,
extras: PublicationExtras = {},
): BlobPublication {
return {
url,
destination,
bytes: request.bytes.byteLength,
...(extras.expiresAt === undefined ? {} : { expiresAt: extras.expiresAt }),
...(extras.delete === undefined ? {} : { delete: extras.delete }),
...(extras.remoteId === undefined ? {} : { remoteId: extras.remoteId }),View on GitHub (pinned to 9690622007)
Solutions
- Read the status in the error message: 401/403 → fix or refresh the credential; 413 → shrink the file; 429 → back off and retry.
- Verify the configured base URL/endpoint for the destination is correct.
- Test the endpoint manually (curl) with the same request to see whether it's auth, size, or availability.
- Check the destination host's status page if the status is 5xx.
Example fix
// before: retry blindly on any failure
await uploader.upload(req);
// after: inspect status and react
try {
await uploader.upload(req);
} catch (err) {
if (/HTTP 429/.test(String(err))) await Bun.sleep(60_000);
else throw err;
} Defensive patterns
Strategy: retry
Validate before calling
// precondition check: config sanity before upload
if (!config.credentials?.apiKey) throw new Error("upload will 401: apiKey not configured"); Try / catch
try {
await expectOk(res, destination);
} catch (err) {
const m = /HTTP (\d{3})/.exec(String(err));
const status = m ? Number(m[1]) : 0;
if (status === 429 || status >= 500) await retryWithBackoff();
else if (status === 401 || status === 403) refreshCredential();
else throw err;
} Prevention
- Check file size against the destination host's documented limit before uploading.
- Rotate credentials proactively and verify them with a lightweight authed request first.
- Implement exponential backoff for 429/5xx and surface 4xx to the user immediately.
- Remember the error is secret-safe: to debug details, reproduce the request manually with curl.
When it happens
Trigger: Any uploader call routed through expectOk — upload, uploadedResponse, listResponse, sessionResponse, permissionResponse — where the remote returns HTTP 4xx or 5xx (401 unauthorized, 403 forbidden, 404, 413 payload too large, 429 rate limit, 5xx outage).
Common situations: Expired or revoked auth token, uploading a file larger than the host's limit, hitting rate limits on public file hosts, destination service downtime, or wrong base URL in config.
Related errors
- Share upload to ${base} failed: ${err instanceof Error ? err
- Share upload to ${base} failed: HTTP ${res.status}${detail ?
- V2 remote compaction failed (${response.status} ${response.s
- sso-role
- HTTP request failed. status=${response.status}; url=${url};
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/c2121e0cbcd0682f.
Report an issue: GitHub.