google-gemini/gemini-cli · error · Error
Environment variable '${envVar}' is not set or is empty. Ple
Error message
Environment variable '${envVar}' is not set or is empty. Please set it before using this agent. What it means
Thrown by resolveAuthValue when a value beginning with '$' names an environment variable that process.env reports as undefined or the empty string. The function is the central resolver for $VAR / !cmd / literal auth values, so this fires for any agent auth field (API key, bearer token, basic password) that uses the $ sigil.
Source
Thrown at packages/core/src/agents/auth-provider/value-resolver.ts:38
* - Any other string: Use as literal value
*
* @param value The value to resolve
* @returns The resolved value
* @throws Error if environment variable is not set or command fails
*/
export async function resolveAuthValue(value: string): Promise<string> {
// Support escaping with double prefix (e.g. $$ or !!).
// Strips one prefix char: $$FOO → $FOO, !!cmd → !cmd (literal, not resolved).
if (value.startsWith('$$') || value.startsWith('!!')) {
return value.slice(1);
}
// Environment variable: $MY_VAR
if (value.startsWith('$')) {
const envVar = value.slice(1);
const resolved = process.env[envVar];
if (resolved === undefined || resolved === '') {
throw new Error(
`Environment variable '${envVar}' is not set or is empty. ` +
`Please set it before using this agent.`,
);
}
debugLogger.debug(`[AuthValueResolver] Resolved env var: ${envVar}`);
return resolved;
}
// Shell command: !command arg1 arg2
if (value.startsWith('!')) {
const command = value.slice(1).trim();
if (!command) {
throw new Error('Empty command in auth value. Expected format: !command');
}
debugLogger.debug(`[AuthValueResolver] Executing command for auth value`);
const shellConfig = getShellConfiguration();View on GitHub (pinned to 5024443c72)
Solutions
- Check the exact variable name spelling and case against what is in the environment: print process.env keys around the failing agent.
- Export the variable in the shell/profile that launches the process (export MY_API_KEY=...).
- If using a .env loader, confirm it runs before the agent auth config is resolved.
- To use a literal value that starts with $, escape it as $$VALUE so the resolver strips one $ and returns the literal.
- If the value should genuinely come from a command instead, use the ! sigil (!gcloud auth print-access-token).
Example fix
# before export apikey='$API_KEY' # shell expands empty / var unset at resolution # after export API_KEY='real-secret-value' # agent config: apiKey: '$API_KEY'
Defensive patterns
Strategy: validation
Validate before calling
import { needsResolution } from './value-resolver.js';
function ensureEnvVars(values) {
for (const v of values) {
if (v.startsWith('$') && !v.startsWith('$$')) {
const name = v.slice(1);
if (process.env[name] === undefined || process.env[name] === '')
throw new Error(`Missing env var ${name}`);
}
}
}
// Call before constructing the agent / auth provider. Type guard
function isResolvableEnvValue(v: string): boolean {
return v.startsWith('$') && !v.startsWith('$$');
} Try / catch
try {
const resolved = await resolveAuthValue('$API_KEY');
} catch (e) {
if (e instanceof Error && e.message.startsWith('Environment variable')) {
// prompt user / load .env / fall back to interactive entry
}
throw e;
} Prevention
- Validate all $-prefixed auth values at startup, before any agent runs.
- Keep env var names in a single constant map to avoid typos.
- Use $$ to escape literal $-prefixed values.
When it happens
Trigger: resolveAuthValue('$MY_API_KEY') is called (transitively from any A2A auth provider that resolves config strings) where process.env.MY_API_KEY is undefined or ''. The double-prefix escape ($$FOO) is the only way to get a literal $FOO, so a single $ always triggers env lookup.
Common situations: Env var typo (case mismatch like $Api_Key vs $API_KEY); forgot to export the var in the shell profile; .env file not loaded in the process that runs the agent; var set in a different shell session; CI secret not injected; var explicitly set to empty string.
Related errors
- The enforced authentication type is '${enforcedType}', but t
- The auth type '${enforcedType}' is enforced, but no authenti
- Please set an Auth method in your ${USER_SETTINGS_PATH} or s
- Failed to get ADC ID token: ${e instanceof Error ? e.message
- Failed to retrieve ADC access token.
AI-assisted analysis of google-gemini/gemini-cli@5024443c72 (2026-08-12).
Data as JSON: /api/errors/7724316acbd73b18.
Report an issue: GitHub.