google-gemini/gemini-cli · error · Error

Missing required variable

Error message

Missing required variable: ${key}

What it means

Thrown by validateVariables when a key in the VariableSchema is marked required: true but the VariableContext has no value (undefined/empty) for that key. hydrateString calls validateVariables first, so any required template variable that is unset aborts hydration.

Solutions

  1. Supply the missing variable in the VariableContext passed to hydrateString.
  2. If the variable is genuinely optional, mark it required:false in the schema.
  3. Resolve values (workspace dir, extension path) before hydration and pass them explicitly.

Example fix

// before
hydrateString('${extensionPath}/bin/run', { });
// after
hydrateString('${extensionPath}/bin/run', { extensionPath: resolvedExtDir });
Defensive patterns

Strategy: validation

Validate before calling

function hasAllRequired(context: VariableContext, schema: VariableSchema): boolean {
  return Object.entries(schema).every(([k, d]) => !d.required || (context[k] != null && context[k] !== ''));
}

Type guard

function hasRequiredVars(context: VariableContext, schema: VariableSchema): boolean { for (const k in schema) { if (schema[k].required && !context[k]) return false; } return true; }

Prevention

When it happens

Trigger: Calling hydrateString on a template that references ${extensionPath} (or another required variable) without supplying that variable in the context; the built-in VARIABLE_SCHEMA marks certain keys required.

Common situations: Extension invoked outside a workspace so extensionPath is undefined; a custom schema marks a variable required but the caller forgets to populate it; env var removed between runs.

Related errors


AI-assisted analysis of google-gemini/gemini-cli@5024443c72 (2026-08-12). Data as JSON: /api/errors/543a35172acf9bdd. Report an issue: GitHub.

Appendix: source

Thrown at packages/cli/src/config/extensions/variables.ts:47

  | string
  | number
  | boolean
  | null
  | JsonObject
  | JsonArray;

export type VariableContext = {
  [key: string]: string | undefined;
};

export function validateVariables(
  variables: VariableContext,
  schema: VariableSchema,
) {
  for (const key in schema) {
    const definition = schema[key];
    if (definition.required && !variables[key]) {
      throw new Error(`Missing required variable: ${key}`);
    }
  }
}

export function hydrateString(str: string, context: VariableContext): string {
  validateVariables(context, VARIABLE_SCHEMA);
  const regex = /\${(.*?)}/g;
  return str.replace(regex, (match, key) => {
    const val = context[key];
    return val == null ? match : String(val);
  });
}

export function recursivelyHydrateStrings<T>(
  obj: T,
  values: VariableContext,
): T {
  if (typeof obj === 'string') {

View on GitHub (pinned to 5024443c72)