{"record":{"id":"543a35172acf9bdd","repo":"google-gemini/gemini-cli","slug":"missing-required-variable-key","errorCode":null,"errorMessage":"Missing required variable: ${key}","messagePattern":"Missing required variable: (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cli/src/config/extensions/variables.ts","lineNumber":47,"sourceCode":"  | string\n  | number\n  | boolean\n  | null\n  | JsonObject\n  | JsonArray;\n\nexport type VariableContext = {\n  [key: string]: string | undefined;\n};\n\nexport function validateVariables(\n  variables: VariableContext,\n  schema: VariableSchema,\n) {\n  for (const key in schema) {\n    const definition = schema[key];\n    if (definition.required && !variables[key]) {\n      throw new Error(`Missing required variable: ${key}`);\n    }\n  }\n}\n\nexport function hydrateString(str: string, context: VariableContext): string {\n  validateVariables(context, VARIABLE_SCHEMA);\n  const regex = /\\${(.*?)}/g;\n  return str.replace(regex, (match, key) => {\n    const val = context[key];\n    return val == null ? match : String(val);\n  });\n}\n\nexport function recursivelyHydrateStrings<T>(\n  obj: T,\n  values: VariableContext,\n): T {\n  if (typeof obj === 'string') {","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/google-gemini/gemini-cli/blob/5024443c7217464a66e98f80d73172a26440bd8f/packages/cli/src/config/extensions/variables.ts#L29-L65","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Supply the missing variable in the VariableContext passed to hydrateString.","If the variable is genuinely optional, mark it required:false in the schema.","Resolve values (workspace dir, extension path) before hydration and pass them explicitly."],"exampleFix":"// before\nhydrateString('${extensionPath}/bin/run', { });\n// after\nhydrateString('${extensionPath}/bin/run', { extensionPath: resolvedExtDir });","handlingStrategy":"validation","validationCode":"function hasAllRequired(context: VariableContext, schema: VariableSchema): boolean {\n  return Object.entries(schema).every(([k, d]) => !d.required || (context[k] != null && context[k] !== ''));\n}","typeGuard":"function hasRequiredVars(context: VariableContext, schema: VariableSchema): boolean { for (const k in schema) { if (schema[k].required && !context[k]) return false; } return true; }","tryCatchPattern":null,"preventionTips":["Resolve workspace/extension paths before hydrating templates.","Mark variables optional in the schema when they are not always needed."],"tags":["extensions","variables","templating","validation"],"backgroundTag":null,"analyzedSha":"5024443c7217464a66e98f80d73172a26440bd8f","analyzedAt":"2026-08-12T06:01:53.711Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}