can1357/oh-my-pi · error
Gemini Files API credential is required
Error message
Gemini Files API credential is required
What it means
createGeminiProviderFileClient() throws synchronously when the model IS an official Google Generative AI model but the credential argument is empty or whitespace-only. The credential becomes the x-goog-api-key header on every Files API request, and uploading without it is guaranteed to fail, so the factory fails fast instead.
Source
Thrown at packages/coding-agent/src/blob-broker/provider-files-gemini.ts:87
baseUrl.search === "" &&
baseUrl.hash === ""
);
} catch {
return false;
}
}
/**
* Create a native Gemini Files API client for a direct Google Generative AI model.
* Unsupported model transports return `null` without issuing a network request.
*/
export function createGeminiProviderFileClient(
model: Model,
credential: string,
fetchImpl: FetchImpl = globalThis.fetch,
): ProviderFileClient | null {
if (!isOfficialGeminiModel(model)) return null;
if (credential.trim().length === 0) throw new Error("Gemini Files API credential is required");
return {
provider: "google",
async upload(request: ProviderFileUploadRequest): Promise<ProviderFileHandle> {
const byteLength = request.bytes.byteLength;
let startResponse: Response;
try {
startResponse = await fetchImpl(GEMINI_FILES_UPLOAD_URL, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Goog-Upload-Command": "start",
"X-Goog-Upload-Header-Content-Length": String(byteLength),
"X-Goog-Upload-Header-Content-Type": request.mimeType,
"X-Goog-Upload-Protocol": "resumable",
"x-goog-api-key": credential,
},
body: JSON.stringify(request.filename ? { file: { display_name: request.filename } } : { file: {} }),View on GitHub (pinned to 9690622007)
Solutions
- Set GEMINI_API_KEY (or your configured credential source) to a valid Google AI Studio API key before constructing the client.
- Trim and check the credential at the call site: if (!key?.trim()) skip or fail before calling the factory.
- Verify you are passing the Google credential, not another provider's key variable.
- Wrap the factory call in try-catch since it throws synchronously for official Gemini models.
Example fix
// before: passing an unvalidated credential
const client = createGeminiProviderFileClient(model, process.env.GEMINI_API_KEY ?? "");
// after: validate first
const key = process.env.GEMINI_API_KEY?.trim();
if (!key) throw new Error("GEMINI_API_KEY is not set");
const client = createGeminiProviderFileClient(model, key); Defensive patterns
Strategy: validation
Validate before calling
const key = process.env.GEMINI_API_KEY?.trim();
if (!key) throw new Error("GEMINI_API_KEY is missing or empty — cannot use Gemini Files API"); Type guard
function hasCredential(v: unknown): v is string {
return typeof v === "string" && v.trim().length > 0;
} Try / catch
try {
const client = createGeminiProviderFileClient(model, key);
} catch (error) {
if (error instanceof Error && error.message.includes("credential is required")) {
// fall back to inline/base64 file attachment instead of Files API upload
} else throw error;
} Prevention
- Fail fast at startup if GEMINI_API_KEY/GOOGLE_API_KEY is unset when Google models are configured
- Never default credentials to empty strings; make the key an explicit required parameter
- Check secret-manager retrieval results for null/empty before use
- Wrap the synchronous factory in try-catch at every call site
When it happens
Trigger: Calling createGeminiProviderFileClient(model, credential) with "" or " " while model.provider==="google", model.api==="google-generative-ai", and baseUrl is exactly https://generativelanguage.googleapis.com/v1beta.
Common situations: GEMINI_API_KEY / GOOGLE_API_KEY env var unset or empty; config file with a blank apikey field; credential sourced from a keychain/secret manager that returned empty; passing the wrong variable into the factory.
Understand the failure class
Background: "API key is required" / "API key not found" / "No API key was set": the missing-api-key error family across 16 libraries — this error's family across 16 libraries.
Related errors
- No API key available for ${model.provider}/${model.id}. Conf
- Unable to resolve AWS credentials. Configure static environm
- profile
- ${providerLabel} login requires onPrompt callback
- Antigravity credentials missing projectId
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/479fc48983df8eb7.
Report an issue: GitHub.