slopus/happy · warning

[Gemini] No API key found. Run 'happy connect gemini' to aut

Error message

[Gemini] No API key found. Run 'happy connect gemini' to authenticate via Google OAuth, or set ${GEMINI_API_KEY_ENV} environment variable.

What it means

createGeminiBackend resolves a Gemini API key from (in order) happy auth storage, local ~/.gemini config, GEMINI_API_KEY, GOOGLE_API_KEY, and an explicit apiKey option. If none is present it logs this warning; the backend is still created but gemini will likely fail to authenticate when launched.

Source

Thrown at packages/happy-cli/src/agent/factories/gemini.ts:92

export function createGeminiBackend(options: GeminiBackendOptions): GeminiBackendResult {

  // Resolve API key from multiple sources (in priority order):
  // 1. Happy cloud OAuth token (via 'happy connect gemini') - highest priority
  // 2. Local Gemini CLI config files (~/.gemini/)
  // 3. GEMINI_API_KEY environment variable
  // 4. GOOGLE_API_KEY environment variable - lowest priority
  
  // Try reading from local Gemini CLI config (token and model)
  const localConfig = readGeminiLocalConfig();
  
  let apiKey = options.cloudToken       // 1. Happy cloud token (passed from runGemini)
    || localConfig.token                // 2. Local config (~/.gemini/)
    || process.env[GEMINI_API_KEY_ENV]  // 3. GEMINI_API_KEY env var
    || process.env[GOOGLE_API_KEY_ENV]  // 4. GOOGLE_API_KEY env var
    || options.apiKey;                  // 5. Explicit apiKey option (fallback)

  if (!apiKey) {
    logger.warn(`[Gemini] No API key found. Run 'happy connect gemini' to authenticate via Google OAuth, or set ${GEMINI_API_KEY_ENV} environment variable.`);
  }

  // Command to run gemini
  const geminiCommand = 'gemini';
  
  // Get model from options, local config, system environment, or use default
  // Priority: options.model (if provided) > local config > env var > default
  // If options.model is undefined, check local config, then env, then use default
  // If options.model is explicitly null, skip local config and use env/default
  const model = determineGeminiModel(options.model, localConfig);

  // Build args - use only --experimental-acp flag
  // Model is passed via GEMINI_MODEL env var (gemini CLI reads it automatically)
  // We don't use --model flag to avoid potential stdout conflicts with ACP protocol
  const geminiArgs = ['--experimental-acp'];

  // Get Google Cloud Project from local config (for Workspace accounts)
  // Only use if: no email stored (global), or email matches current user

View on GitHub (pinned to b824cd0a46)

Solutions

  1. Run `happy connect gemini` to authenticate via Google OAuth.
  2. Or export GEMINI_API_KEY=<your-key> (or GOOGLE_API_KEY) in the environment where happy runs.
  3. If using the daemon, set the env var in the daemon's environment and restart it, since daemons don't inherit your shell env.
  4. Verify with `echo $GEMINI_API_KEY` that the variable is set and non-empty in the actual execution environment.

Example fix

// before
happy gemini  // warn: no API key
// after
export GEMINI_API_KEY=AIza...
happy gemini
Defensive patterns

Strategy: validation

Validate before calling

if (!process.env.GEMINI_API_KEY && !process.env.GOOGLE_API_KEY && !fs.existsSync(require('os').homedir() + '/.gemini/oauth_creds.json')) {
  console.error('No Gemini credentials: run `happy connect gemini` or export GEMINI_API_KEY.');
  process.exit(1);
}

Prevention

When it happens

Trigger: Running happy with the gemini agent (happy gemini) before ever running 'happy connect gemini', with no GEMINI_API_KEY/GOOGLE_API_KEY env var set in the current (or daemon) environment, and no apiKey in options.

Common situations: Fresh machine after cloning dotfiles without the key, CI/daemon environment that lacks the interactive shell's exported GEMINI_API_KEY, or key stored in ~/.gemini that was wiped/reinstalled.

Understand the failure class

Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of slopus/happy@b824cd0a46 (2026-08-31). Data as JSON: /api/errors/495dd60268f55015. Report an issue: GitHub.