can1357/oh-my-pi · error
Gemini Files API finalize response is missing ${field}
Error message
Gemini Files API finalize response is missing ${field} What it means
requireString() throws this when a required field of the Gemini Files API finalize response's file object is absent, not a string, or an empty string. The library treats every one of file.state/file.name/file.uri/file.mimeType/file.expirationTime as mandatory to build a usable ProviderFileHandle, so a partially-populated response is rejected rather than propagated with undefined fields.
Source
Thrown at packages/coding-agent/src/blob-broker/provider-files-gemini.ts:34
function responseObject(value: unknown, context: string): Record<string, unknown> {
if (typeof value !== "object" || value === null || Array.isArray(value)) {
throw new Error(`Gemini Files API ${context} response is not a JSON object`);
}
return value as Record<string, unknown>;
}
async function responseJson(response: Response, context: string): Promise<Record<string, unknown>> {
try {
return responseObject((await response.json()) as unknown, context);
} catch (error) {
if (error instanceof Error && error.message.startsWith("Gemini Files API")) throw error;
throw new Error(`Gemini Files API ${context} response is not valid JSON`);
}
}
function requireString(value: unknown, field: string): string {
if (typeof value !== "string" || value.length === 0) {
throw new Error(`Gemini Files API finalize response is missing ${field}`);
}
return value;
}
function parseFinalizedFile(payload: Record<string, unknown>): GeminiFileResource {
const file = responseObject(payload.file, "finalize file");
const state = requireString(file.state, "file.state");
if (state !== "ACTIVE") throw new Error("Gemini Files API finalized file state is not ACTIVE");
const name = requireString(file.name, "file.name");
if (!/^files\/[^/]+$/.test(name)) {
throw new Error("Gemini Files API finalize response contains an invalid file.name");
}
const uri = requireString(file.uri, "file.uri");
const mimeType = requireString(file.mimeType, "file.mimeType");
const expirationTime = requireString(file.expirationTime, "file.expirationTime");
const expiresAt = Date.parse(expirationTime);
if (!Number.isFinite(expiresAt)) {View on GitHub (pinned to 9690622007)
Solutions
- Log the raw finalize response body to see which field is missing and what replaced it.
- Check for Google API schema/preview-version changes in the v1beta Files API release notes.
- Retry the upload — a finalize that lands before the file record is fully materialized can come back incomplete.
- Update the package if a newer version adapts to a changed response shape.
Example fix
// before: brittle full-schema assumption
catch (e) { throw new Error("upload failed: " + e.message); }
// after: inspect and adapt
const raw = await finalizeResponse.text();
console.error("finalize payload:", raw); // then fix expectations or file a bug Defensive patterns
Strategy: type-guard
Validate before calling
null
Type guard
function isCompleteGeminiFile(f: unknown): f is { state: string; name: string; uri: string; mimeType: string; expirationTime: string } {
if (typeof f !== "object" || f === null) return false;
const o = f as Record<string, unknown>;
return ["state", "name", "uri", "mimeType", "expirationTime"].every(k => typeof o[k] === "string" && o[k].length > 0);
} Try / catch
try {
const handle = await client.upload(request);
} catch (error) {
if (error instanceof Error && /missing file\./.test(error.message)) {
logger.error("Gemini finalize response incomplete", { field: error.message });
// pin/upgrade SDK version or report schema drift
} else throw error;
} Prevention
- Pin to a maintained package version and read changelogs for Files API schema updates
- Log raw API responses (debug FetchImpl) in staging to catch schema drift early
- Keep mock responses in tests derived from real captured payloads
- Monitor Google Workspace/AI release notes for v1beta Files API changes
When it happens
Trigger: parseFinalizedFile calls requireString(file.X, "file.X") and Google's finalize payload omits or empty-strings that field; the message interpolates the exact missing field name (e.g. 'finalize response is missing file.uri').
Common situations: Google changes or versions the v1beta Files API response schema; an unexpected state value shortens the payload; mock/stub responses in tests missing fields; a proxy stripping fields.
Understand the failure class
Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.
Related errors
- Gemini Files API ${context} response is not valid JSON
- Gemini Files API finalize response contains an invalid file.
- seafile upload-link response did not include a URL
- Replacement text is not valid UTF-8: {err}
- V2 compaction stream parse failed: ${err instanceof Error ?
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/ef68ada65b83c3ff.
Report an issue: GitHub.