{"record":{"id":"fd09d7333d67bcb9","repo":"can1357/oh-my-pi","slug":"gemini-files-api-delete-failed-with-http-respons","errorCode":null,"errorMessage":"Gemini Files API delete failed with HTTP ${response.status}","messagePattern":"Gemini Files API delete failed with HTTP (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/blob-broker/provider-files-gemini.ts","lineNumber":169,"sourceCode":"\t\t\t};\n\t\t},\n\t\tasync delete(handle: ProviderFileHandle): Promise<void> {\n\t\t\tif (handle.provider !== \"google\")\n\t\t\t\tthrow new Error(\"Gemini Files API cannot delete a handle from another provider\");\n\t\t\tconst name = handle.id;\n\t\t\tif (typeof name !== \"string\" || !/^files\\/[^/]+$/.test(name)) {\n\t\t\t\tthrow new Error(\"Gemini Files API delete requires a valid file name\");\n\t\t\t}\n\t\t\tlet response: Response;\n\t\t\ttry {\n\t\t\t\tresponse = await fetchImpl(`${GEMINI_FILES_RESOURCE_URL}/${name}`, {\n\t\t\t\t\tmethod: \"DELETE\",\n\t\t\t\t\theaders: { \"x-goog-api-key\": credential },\n\t\t\t\t});\n\t\t\t} catch {\n\t\t\t\tthrow new Error(\"Gemini Files API delete request failed\");\n\t\t\t}\n\t\t\tif (!response.ok) throw new Error(`Gemini Files API delete failed with HTTP ${response.status}`);\n\t\t},\n\t};\n}\n","sourceCodeStart":151,"sourceCodeEnd":173,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/blob-broker/provider-files-gemini.ts#L151-L173","documentation":"Thrown by the Gemini provider's delete() when the DELETE request completed but Gemini returned a non-2xx HTTP status. The status code is embedded in the message so developers can tell authorization problems (401/403) from missing files (404) or rate limits (429).","triggerScenarios":"Calling delete() and receiving e.g. 401/403 (bad API key), 404 (file already deleted or never existed), 429 (quota exceeded), or 5xx from the Gemini Files API delete endpoint.","commonSituations":"Deleting a file that was already removed (404 — often from a concurrent cleanup or double-delete); revoked/expired API key; per-minute quota exhaustion when bulk-deleting many files; Gemini incident causing 5xx.","solutions":["Treat HTTP 404 as success for cleanup purposes — the file is already gone; do not retry.","For 401/403, re-check the Gemini API key and its Files API permissions.","For 429, add backoff/throttling to bulk deletes to respect per-minute quotas.","Retry 5xx with exponential backoff; deletes are idempotent so retries are safe.","Wrap cleanup loops to continue on individual delete failures instead of aborting the whole batch."],"exampleFix":"// before: failing cleanup on already-deleted file\nawait geminiClient.delete(handle);\n// after\ntry {\n  await geminiClient.delete(handle);\n} catch (err) {\n  if (!/HTTP 404/.test(err.message)) throw err; // already deleted: fine\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await geminiClient.delete(handle);\n} catch (err) {\n  const status = Number(/HTTP (\\d{3})/.exec(err.message ?? \"\")?.[1] ?? 0);\n  if (status === 404) return; // already deleted\n  if (status === 429 || status >= 500) await retryWithBackoff();\n  else throw err; // 401/403: credential problem\n}","preventionTips":["Treat 404 on delete as success in cleanup code","Throttle bulk deletes to avoid 429s","Rotate/verify API keys before cleanup jobs run","Retry 5xx with backoff; never retry 4xx auth errors"],"tags":["network","http","gemini","file-delete","api-key"],"backgroundTag":"file-delete-http-error","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}