google-gemini/gemini-cli · error

Invalid path: Directory traversal not allowed.

Error message

Invalid path: Directory traversal not allowed.

What it means

Security guard thrown during skill installation from a remote/local source when resolving the source path against the temp clone directory would escape it (directory traversal). isPathTraversal returns true if the relative path is '..', starts with '../', or is absolute — preventing a malicious subpath argument from reading outside the temp dir.

Source

Thrown at packages/cli/src/utils/skillUtils.ts:151

      sourcePath = tempDirToClean;

      onLog(`Extracting skill from ${source}...`);
      await extract(path.resolve(source), { dir: tempDirToClean });
    }

    // If a subpath is provided, resolve it against the cloned/local root.
    if (subpath) {
      sourcePath = path.join(sourcePath, subpath);
    }

    sourcePath = path.resolve(sourcePath);

    // Quick security check to prevent directory traversal out of temp dir when cloning
    if (tempDirToClean) {
      const resolvedTemp = path.resolve(tempDirToClean);
      const relative = path.relative(resolvedTemp, sourcePath);
      if (isPathTraversal(relative)) {
        throw new Error('Invalid path: Directory traversal not allowed.');
      }
    }

    onLog(`Searching for skills in ${sourcePath}...`);
    const skills = await loadSkillsFromDir(sourcePath);

    if (skills.length === 0) {
      throw new Error(
        `No valid skills found in ${source}${subpath ? ` at path "${subpath}"` : ''}. Ensure a SKILL.md file exists with valid frontmatter.`,
      );
    }

    const workspaceDir = process.cwd();
    const storage = new Storage(workspaceDir);
    const targetDir =
      scope === 'workspace'
        ? storage.getProjectSkillsDir()
        : Storage.getUserSkillsDir();

View on GitHub (pinned to 5024443c72)

Solutions

  1. Use a subpath that stays within the skill source root (no '../', no leading '/').
  2. If installing from a local dir, point `source` directly at the skill folder instead of using a subpath escape.
  3. Audit any third-party skill source for malicious path declarations before installing.

Example fix

// before
// installSkill({ source: 'https://github.com/x/y', subpath: '../../../etc' })

// after
// installSkill({ source: 'https://github.com/x/y', subpath: 'skills/my-skill' })
Defensive patterns

Strategy: validation

Validate before calling

const path = require('path');
function assertNoTraversal(baseDir, target) {
  const rel = path.relative(path.resolve(baseDir), path.resolve(baseDir, target));
  if (rel === '..' || rel.startsWith('..' + path.sep) || path.isAbsolute(rel)) {
    throw new Error('Subpath escapes the skill source root');
  }
}

Type guard

const isSafeSubpath = (baseDir, sub) => {
  const rel = path.relative(path.resolve(baseDir), path.resolve(baseDir, sub));
  return rel !== '..' && !rel.startsWith('..' + path.sep) && !path.isAbsolute(rel);
};

Prevention

When it happens

Trigger: A `subpath` argument like '../../../etc' or an absolute path is supplied when installing a skill from a source that was cloned into tempDirToClean, making path.relative(tempDir, sourcePath) escape upward.

Common situations: User passes a subpath with leading '../'. A skill registry/URL serves a SKILL.md whose declared paths attempt traversal. Absolute subpath supplied. Misconfigured source URL whose repo layout differs from expectations.

Related errors


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