google-gemini/gemini-cli · error

Extension validation failed.

Error message

Extension validation failed.

What it means

The 'gemini extensions validate' command runs structural checks on an extension directory. Currently it verifies that context files listed in gemini-extension.json's contextFileName field actually exist on disk. If any check produces an error, the individual errors are logged via debugLogger.error() and then this aggregate error is thrown.

Source

Thrown at packages/cli/src/commands/extensions/validate.ts:87

  if (!semver.valid(extensionConfig.version)) {
    warnings.push(
      `Warning: Version '${extensionConfig.version}' does not appear to be standard semver (e.g., 1.0.0).`,
    );
  }

  if (warnings.length > 0) {
    debugLogger.warn('Validation warnings:');
    for (const warning of warnings) {
      debugLogger.warn(`  - ${warning}`);
    }
  }

  if (errors.length > 0) {
    debugLogger.error('Validation failed with the following errors:');
    for (const error of errors) {
      debugLogger.error(`  - ${error}`);
    }
    throw new Error('Extension validation failed.');
  }
}

export const validateCommand: CommandModule = {
  command: 'validate <path>',
  describe: 'Validates an extension from a local path.',
  builder: (yargs) =>
    yargs.positional('path', {
      describe: 'The path of the extension to validate.',
      type: 'string',
      demandOption: true,
    }),
  handler: async (args) => {
    await handleValidate({
      // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
      path: args['path'] as string,
    });
    await exitCli();

View on GitHub (pinned to 5024443c72)

Solutions

  1. Read the individual error messages logged before the throw to identify which files are missing.
  2. Create the missing context files or fix their paths in gemini-extension.json.
  3. Remove stale contextFileName entries from the manifest if the files are no longer needed.

Example fix

// before (gemini-extension.json)
{
  "contextFileName": ["docs/README.md", "docs/rules.md"]
}
// docs/rules.md does not exist -> validation fails

// after
{
  "contextFileName": ["docs/README.md"]
}
// or create docs/rules.md
Defensive patterns

Strategy: try-catch

Validate before calling

import * as fs from 'node:fs';
import * as path from 'node:path';

function validateContextFilesExist(
  extensionPath: string,
  contextFileNames: string[] | string,
): string[] {
  const names = Array.isArray(contextFileNames) ? contextFileNames : [contextFileNames];
  const missing: string[] = [];
  for (const name of names) {
    const abs = path.resolve(extensionPath, name);
    if (!fs.existsSync(abs)) {
      missing.push(name);
    }
  }
  return missing;
}

// Pre-check before running validate:
const missing = validateContextFilesExist(extPath, config.contextFileName);
if (missing.length > 0) {
  console.error('Missing context files:', missing);
}

Try / catch

try {
  await handleValidate({ path: extPath });
} catch (e) {
  if (e instanceof Error && e.message === 'Extension validation failed.') {
    // Individual errors were already logged by debugLogger.error
    // Review the console output to see which checks failed
    process.exit(1);
  }
  throw e;
}

Prevention

When it happens

Trigger: Running 'gemini extensions validate ./my-ext' where gemini-extension.json contains a contextFileName entry (e.g., 'docs/context.md') that does not exist as a file at the resolved path within the extension directory.

Common situations: Extension manifest references context files that were never created, were renamed, or have incorrect relative paths; packaging an extension without including all referenced files; case-sensitivity mismatch on Linux.

Related errors


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