can1357/oh-my-pi · error
Gemini Files API delete requires a valid file name
Error message
Gemini Files API delete requires a valid file name
What it means
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.
Source
Thrown at packages/coding-agent/src/blob-broker/provider-files-gemini.ts:158
provider: "google",
id: file.name,
uri: file.uri,
mimeType: file.mimeType,
bytes: byteLength,
expiresAt: file.expiresAt,
delete: {
method: "DELETE",
url: `${GEMINI_FILES_RESOURCE_URL}/${file.name}`,
headers: { "x-goog-api-key": credential },
},
};
},
async delete(handle: ProviderFileHandle): Promise<void> {
if (handle.provider !== "google")
throw new Error("Gemini Files API cannot delete a handle from another provider");
const name = handle.id;
if (typeof name !== "string" || !/^files\/[^/]+$/.test(name)) {
throw new Error("Gemini Files API delete requires a valid file name");
}
let response: Response;
try {
response = await fetchImpl(`${GEMINI_FILES_RESOURCE_URL}/${name}`, {
method: "DELETE",
headers: { "x-goog-api-key": credential },
});
} catch {
throw new Error("Gemini Files API delete request failed");
}
if (!response.ok) throw new Error(`Gemini Files API delete failed with HTTP ${response.status}`);
},
};
}
View on GitHub (pinned to 9690622007)
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.
Example fix
// before
await geminiClient.delete({ provider: "google", id: file.uri });
// after
const id = new URL(file.uri).pathname.split("/").slice(-2).join("/"); // "files/abc123"
if (!/^files\/[^/]+$/.test(id)) throw new Error("unexpected Gemini file id");
await geminiClient.delete({ provider: "google", id }); Defensive patterns
Strategy: validation
Validate before calling
const GEMINI_FILE_NAME = /^files\/[^/]+$/;
if (typeof handle.id !== "string" || !GEMINI_FILE_NAME.test(handle.id)) {
throw new Error(`not a valid Gemini file name: ${String(handle.id)}`);
} Type guard
function hasValidGeminiFileId(h: ProviderFileHandle): boolean {
return typeof h.id === "string" && /^files\/[^/]+$/.test(h.id);
} Prevention
- 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
When it happens
Trigger: 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").
Common situations: 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.
Related errors
- Gemini Files API cannot delete a handle from another provide
- Gemini Files API delete request failed
- Gemini Files API delete failed with HTTP ${response.status}
- maxAgents must be a positive integer
- Unsupported vault:// file op: ${rawOp}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/9b551a087f3b596e.
Report an issue: GitHub.