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
- Use a subpath that stays within the skill source root (no '../', no leading '/').
- If installing from a local dir, point `source` directly at the skill folder instead of using a subpath escape.
- 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
- Reject subpaths containing '..' or leading '/' at the input boundary.
- Treat third-party skill sources as untrusted until audited.
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
- Invalid skill name: Path traversal detected.
- Invalid taskId: ${taskId}
- Security violation: Null byte detected in path.
- Security violation: The path "${trimmedPath}" is outside the
- No valid skills found in ${source}${subpath ? ` at path "${s
AI-assisted analysis of google-gemini/gemini-cli@5024443c72 (2026-08-12).
Data as JSON: /api/errors/d3d6803fccb2ee26.
Report an issue: GitHub.