{"record":{"id":"9b551a087f3b596e","repo":"can1357/oh-my-pi","slug":"gemini-files-api-delete-requires-a-valid-file-name","errorCode":null,"errorMessage":"Gemini Files API delete requires a valid file name","messagePattern":"Gemini Files API delete requires a valid file name","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/blob-broker/provider-files-gemini.ts","lineNumber":158,"sourceCode":"\t\t\t\tprovider: \"google\",\n\t\t\t\tid: file.name,\n\t\t\t\turi: file.uri,\n\t\t\t\tmimeType: file.mimeType,\n\t\t\t\tbytes: byteLength,\n\t\t\t\texpiresAt: file.expiresAt,\n\t\t\t\tdelete: {\n\t\t\t\t\tmethod: \"DELETE\",\n\t\t\t\t\turl: `${GEMINI_FILES_RESOURCE_URL}/${file.name}`,\n\t\t\t\t\theaders: { \"x-goog-api-key\": credential },\n\t\t\t\t},\n\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":140,"sourceCodeEnd":173,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/blob-broker/provider-files-gemini.ts#L140-L173","documentation":"Thrown by the Gemini provider's delete() when handle.id is not a string or does not match the Gemini Files API file-name format ^files/[^/]+$ (e.g. \"files/abc123\"). The library validates the resource name before building the DELETE URL to avoid malformed requests to the Gemini API.","triggerScenarios":"Calling delete() with a handle whose id is missing, a number, an empty string, lacks the \"files/\" prefix, or contains an extra path segment (e.g. \"https://...\", \"files/a/b\", a raw OpenAI file id like \"file-Xyz\").","commonSituations":"Hand-constructing ProviderFileHandle objects instead of using upload() output; storing only the id string and rebuilding the handle incorrectly; copying ids from other Google APIs (generative language full resource URLs); truncating ids in logs/UI before reuse.","solutions":["Use the handle exactly as returned by the Gemini client's upload(); do not reconstruct it manually.","If you have a full resource URL or URI, extract the \"files/<name>\" portion: id = uri.split(\"/\").slice(-2).join(\"/\").","Validate before calling: /^files\\/[^/]+$/.test(handle.id).","Check your persistence layer is not truncating or transforming the id on save/load.","Ensure you are not passing an OpenAI/other-provider file id here — check handle.provider first."],"exampleFix":"// before\nawait geminiClient.delete({ provider: \"google\", id: file.uri });\n// after\nconst id = new URL(file.uri).pathname.split(\"/\").slice(-2).join(\"/\"); // \"files/abc123\"\nif (!/^files\\/[^/]+$/.test(id)) throw new Error(\"unexpected Gemini file id\");\nawait geminiClient.delete({ provider: \"google\", id });","handlingStrategy":"validation","validationCode":"const GEMINI_FILE_NAME = /^files\\/[^/]+$/;\nif (typeof handle.id !== \"string\" || !GEMINI_FILE_NAME.test(handle.id)) {\n  throw new Error(`not a valid Gemini file name: ${String(handle.id)}`);\n}","typeGuard":"function hasValidGeminiFileId(h: ProviderFileHandle): boolean {\n  return typeof h.id === \"string\" && /^files\\/[^/]+$/.test(h.id);\n}","tryCatchPattern":null,"preventionTips":["Only use handles returned by upload(); never hand-build ProviderFileHandle objects","Extract \"files/<name>\" from full URIs before storing ids","Validate stored ids at load time (fail fast on corrupted persistence)","Check handle.provider before assuming the id format"],"tags":["validation","gemini","file-delete","handle","api-misuse"],"backgroundTag":"invalid-resource-id","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}