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.

Solutions

  1. Use the handle exactly as returned by the Gemini client's upload(); do not reconstruct it manually.
  2. If you have a full resource URL or URI, extract the "files/<name>" portion: id = uri.split("/").slice(-2).join("/").
  3. Validate before calling: /^files\/[^/]+$/.test(handle.id).
  4. Check your persistence layer is not truncating or transforming the id on save/load.
  5. 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

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


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/9b551a087f3b596e. Report an issue: GitHub.

Appendix: 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)