can1357/oh-my-pi · error
Gemini Files API upload initialization failed with HTTP ${st
Error message
Gemini Files API upload initialization failed with HTTP ${startResponse.status} What it means
The 'start' resumable-upload POST completed but returned a non-2xx status; the client includes that status code in the message. Google rejected the initialization request itself — the byte payload was never sent, so this is about the metadata/start handshake, not the file content.
Source
Thrown at packages/coding-agent/src/blob-broker/provider-files-gemini.ts:112
try {
startResponse = await fetchImpl(GEMINI_FILES_UPLOAD_URL, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Goog-Upload-Command": "start",
"X-Goog-Upload-Header-Content-Length": String(byteLength),
"X-Goog-Upload-Header-Content-Type": request.mimeType,
"X-Goog-Upload-Protocol": "resumable",
"x-goog-api-key": credential,
},
body: JSON.stringify(request.filename ? { file: { display_name: request.filename } } : { file: {} }),
signal: request.signal,
});
} catch {
throw new Error("Gemini Files API upload initialization request failed");
}
if (!startResponse.ok) {
throw new Error(`Gemini Files API upload initialization failed with HTTP ${startResponse.status}`);
}
const uploadUrl = startResponse.headers.get("X-Goog-Upload-URL")?.trim();
if (!uploadUrl)
throw new Error("Gemini Files API upload initialization response is missing X-Goog-Upload-URL");
let finalizeResponse: Response;
try {
finalizeResponse = await fetchImpl(uploadUrl, {
method: "POST",
headers: {
"Content-Length": String(byteLength),
"X-Goog-Upload-Command": "upload, finalize",
"X-Goog-Upload-Offset": "0",
},
body: request.bytes,
signal: request.signal,
});View on GitHub (pinned to 9690622007)
Solutions
- Read the HTTP status from the message: 401/403 → fix the API key / enable the Generative Language API; 429 → check quota; 5xx → retry later.
- Verify the API key is valid via curl 'https://generativelanguage.googleapis.com/v1beta/files?key=...'.
- Confirm the request mimeType header matches the file and is a supported Gemini Files API type.
- For 5xx/429, retry with exponential backoff.
- Capture the response body with a debug FetchImpl wrapper for Google's detailed error JSON.
Example fix
// before: treating all failures the same
await client.upload(request);
// after: branch on status from the message
const m = /HTTP (\d+)/.exec(String(e.message));
if (m && (m[1] === "429" || m[1].startsWith("5"))) return retryWithBackoff(upload);
if (m && (m[1] === "401" || m[1] === "403")) throw new Error("Check GEMINI_API_KEY"); Defensive patterns
Strategy: try-catch
Validate before calling
// pre-validate the credential against the API before large uploads
const probe = await fetch("https://generativelanguage.googleapis.com/v1beta/files", {
headers: { "x-goog-api-key": key },
});
if (probe.status === 401 || probe.status === 403) throw new Error("Gemini API key invalid or API not enabled"); Type guard
null
Try / catch
try {
const handle = await client.upload(request);
} catch (error) {
const status = /HTTP (\d+)/.exec(error instanceof Error ? error.message : "")?.[1];
if (status === "401" || status === "403") throw new Error("Fix GEMINI_API_KEY / enable Generative Language API");
if (status === "429" || status?.startsWith("5")) return retryWithBackoff(upload);
throw error;
} Prevention
- Validate the API key with a lightweight GET /v1beta/files call before big uploads
- Ensure the Generative Language API is enabled on the key's Google Cloud project
- Respect quota limits and back off on 429
- Check request.mimeType correctness — mismatched content types get 4xx on start
When it happens
Trigger: fetchImpl POST to /upload/v1beta/files with X-Goog-Upload-Command: start returns e.g. 400 (bad display_name/header content-type), 403 (invalid API key / API not enabled), 429 (quota), or 5xx (Google outage).
Common situations: Invalid or revoked Gemini API key (403); Generative Language API not enabled for the key's project; exceeding upload quota or file-size limits (4xx/429); mimeType not matching the actual file; transient 500/503 during Google incidents.
Related errors
- sso-role
- Gemini Files API finalized file state is not ACTIVE
- Gemini Files API upload initialization response is missing X
- OpenAI Files API upload failed with HTTP ${response.status}
- ${destination} upload failed with HTTP ${status}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/ec918d974d6d4f6b.
Report an issue: GitHub.