can1357/oh-my-pi · error
Gemini Files API cannot delete a handle from another provide
Error message
Gemini Files API cannot delete a handle from another provider
What it means
Thrown by the Gemini provider's delete() when the supplied ProviderFileHandle was issued by a different provider (handle.provider !== "google"). Provider file handles are provider-scoped: a handle holding an OpenAI file id cannot be deleted through the Gemini Files API, so the library fails fast with a clear message instead of making a doomed request.
Source
Thrown at packages/coding-agent/src/blob-broker/provider-files-gemini.ts:155
const file = parseFinalizedFile(await responseJson(finalizeResponse, "finalize"));
return {
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
- Route each handle to the client whose provider matches handle.provider before calling delete().
- Store the provider alongside the handle id in your persistence layer and look up the correct client by that field.
- If migrating between providers, re-upload the file to the new provider and use the newly returned handle.
- Add a guard/dispatch map in caller code: { google: geminiClient, openai: openaiClient }[handle.provider].delete(handle).
Example fix
// before
geminiClient.delete(handle); // handle.provider === "openai"
// after
if (handle.provider === "google") {
await geminiClient.delete(handle);
} else {
await openaiClient.delete(handle);
} Defensive patterns
Strategy: type-guard
Type guard
function isGoogleHandle(h: ProviderFileHandle): h is ProviderFileHandle & { provider: "google" } {
return h.provider === "google";
}
// call site: if (!isGoogleHandle(handle)) routeToOtherProvider(handle); Prevention
- Always dispatch deletes through a provider-keyed map instead of calling a specific client
- Persist handle.provider together with handle.id
- Never share handles across sessions that switch model providers
- Type the handle narrowly (branded google/openai types) so mismatches fail at compile time
When it happens
Trigger: Calling delete() on the Gemini file client with a handle whose provider field is e.g. "openai" — typically because the handle was returned by a different provider's upload or stored in shared state (session, DB) and passed to the wrong client.
Common situations: Mixing multiple blob-broker providers (OpenAI and Gemini) in one session and routing cleanup through a single client; persisting handles without the provider field and reconstructing them with the wrong client; switching model providers mid-session while retaining old file handles.
Related errors
- Gemini Files API delete requires a valid file name
- No messages to continue from
- Cannot continue from message role: assistant
- Gemini Files API ${context} response is not a JSON object
- Gemini Files API upload finalization failed with HTTP ${fina
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/698a5bae784fbfbc.
Report an issue: GitHub.