danny-avila/LibreChat · error · Error

Gemini Image Generation requires one of: user-provided API k

Error message

Gemini Image Generation requires one of: user-provided API key, GEMINI_API_KEY or GOOGLE_KEY env var, or a valid Google service account. Service account file not found or invalid at: ${credentialsPath}

What it means

Thrown by initializeGeminiClient when no API key path is available and the Vertex AI service-account fallback also fails. The function tries, in order: options.GEMINI_API_KEY, options.GOOGLE_KEY (both resolved upstream by loadAuthValues), then a service-account JSON at GOOGLE_SERVICE_KEY_FILE or api/data/auth.json. The throw fires only if the loaded file is missing, unreadable, or lacks a project_id field.

Source

Thrown at api/app/clients/tools/structured/GeminiImageGen.js:113

async function initializeGeminiClient(options = {}) {
  const geminiKey = options.GEMINI_API_KEY;
  if (geminiKey) {
    logger.debug('[GeminiImageGen] Using Gemini API with GEMINI_API_KEY');
    return new GoogleGenAI({ apiKey: geminiKey });
  }

  const googleKey = options.GOOGLE_KEY;
  if (googleKey) {
    logger.debug('[GeminiImageGen] Using Gemini API with GOOGLE_KEY');
    return new GoogleGenAI({ apiKey: googleKey });
  }

  logger.debug('[GeminiImageGen] Using Vertex AI with service account');
  const credentialsPath = getDefaultServiceKeyPath();
  const serviceKey = await loadServiceKey(credentialsPath);

  if (!serviceKey || !serviceKey.project_id) {
    throw new Error(
      'Gemini Image Generation requires one of: user-provided API key, GEMINI_API_KEY or GOOGLE_KEY env var, or a valid Google service account. ' +
        `Service account file not found or invalid at: ${credentialsPath}`,
    );
  }

  return new GoogleGenAI({
    vertexai: true,
    project: serviceKey.project_id,
    location: process.env.GOOGLE_CLOUD_LOCATION || process.env.GOOGLE_LOC || 'global',
    googleAuthOptions: { credentials: serviceKey },
  });
}

/**
 * Convert image files to Gemini inline data format
 * @param {Object} params - Parameters
 * @returns {Promise<Array>} - Array of inline data objects
 */

View on GitHub (pinned to 5ff282f900)

Solutions

  1. Set `GEMINI_API_KEY` (or `GOOGLE_KEY`) in .env for the simplest path — the API-key branch returns before touching any file.
  2. If using Vertex AI, put a valid service-account JSON at api/data/auth.json or set GOOGLE_SERVICE_KEY_FILE to its absolute path, and confirm the JSON contains a `project_id` field.
  3. Validate the file with `node -e "const k=require('./api/data/auth.json'); console.log(k.project_id)"` to ensure project_id resolves.
  4. If loadAuthValues is supposed to inject the key, check that the user/endpoint credential flow actually populated GEMINI_API_KEY before the tool runs.

Example fix

// before — no key env, missing/invalid service account
const t = createGeminiImageTool({ /* no GEMINI_API_KEY/GOOGLE_KEY */ });
await t.invoke({ prompt: 'a fox' }); // throws

// after — simplest fix: API key via env
// .env: GEMINI_API_KEY=AIza...

// or — Vertex AI: valid service account
// api/data/auth.json must contain { "project_id": "my-gcp-project", ... }
Defensive patterns

Strategy: validation

Validate before calling

async function ensureGeminiCreds(fields = {}) {
  const hasKey = Boolean(fields.GEMINI_API_KEY || fields.GOOGLE_KEY);
  if (hasKey) return;
  const fs = require('fs');
  const path = require('path');
  const credPath = process.env.GOOGLE_SERVICE_KEY_FILE || path.join(process.cwd(), 'api', 'data', 'auth.json');
  if (!fs.existsSync(credPath)) {
    throw new Error('No Gemini API key and no service account at ' + credPath);
  }
  const key = JSON.parse(fs.readFileSync(credPath, 'utf8'));
  if (!key.project_id) throw new Error('Service account JSON missing project_id at ' + credPath);
}

Type guard

function hasGeminiCreds(fields) {
  return Boolean(fields?.GEMINI_API_KEY || fields?.GOOGLE_KEY);
}

Try / catch

try {
  await geminiTool.invoke({ prompt });
} catch (e) {
  if (/Gemini Image Generation requires/.test(e.message)) {
    return 'Gemini image generation is not configured (API key or service account required).';
  }
  throw e;
}

Prevention

When it happens

Trigger: Creating the Gemini image tool (which calls initializeGeminiClient on first image request) when (a) neither GEMINI_API_KEY nor GOOGLE_KEY was resolved into the fields, AND (b) loadServiceKey(credentialsPath) returned null/undefined OR the parsed JSON has no project_id.

Common situations: First-run setup that never placed a Google service-account JSON at api/data/auth.json; GOOGLE_SERVICE_KEY_FILE points to a stale or deleted path; the JSON is a non-service-account key (e.g., an OAuth client secret) that has no project_id; the file exists but is empty/corrupt; running in a container without the mounted secret volume.

Related errors


AI-assisted analysis of danny-avila/LibreChat@5ff282f900 (2026-08-12). Data as JSON: /api/errors/614776af069c4136. Report an issue: GitHub.