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

  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.