n8n-io/n8n · warning · Error
Pattern "${pattern}" escapes the base directory
Error message
Pattern "${pattern}" escapes the base directory What it means
Thrown by assertPatternStaysInside() (called from the search_files tool) when a glob pattern starts with '/' (absolute path) or contains '..' as a segment. This prevents the search tool from escaping the base directory via the pattern itself, complementing the per-file path resolution guard.
Source
Thrown at packages/@n8n/computer-use/src/tools/filesystem/search-files.ts:114
return formatCallToolResult({
name,
query,
matches: matches.slice(0, limit),
truncated: matches.length > limit,
totalMatches: matches.length,
});
},
};
interface ResolvedFile {
path: string;
absolutePath: string;
}
function assertPatternStaysInside(pattern: string): void {
if (pattern.startsWith('/') || pattern.split('/').includes('..')) {
throw new Error(`Pattern "${pattern}" escapes the base directory`);
}
}
async function grepFile(
file: ResolvedFile,
regex: RegExp,
): Promise<Array<{ path: string; lineNumber: number; line: string }>> {
try {
const stat = await fs.stat(file.absolutePath);
if (stat.size > MAX_FILE_SIZE) return [];
const buffer = await fs.readFile(file.absolutePath);
if (isLikelyBinaryContent(buffer)) return [];
const lines = buffer.toString('utf-8').split('\n');
const hits: Array<{ path: string; lineNumber: number; line: string }> = [];
for (let i = 0; i < lines.length; i++) {
if (regex.test(lines[i])) {View on GitHub (pinned to 5ac6606e81)
Solutions
- Use relative patterns only (e.g. 'src/**/*.ts', '**/*.json')
- Remove any leading '/' from the pattern
- Remove all '..' segments from the pattern
Example fix
// before (pattern escapes base directory):
await search_files({ pattern: 'ERROR', glob: '../syslog/**' });
// after (use a relative pattern within the base directory):
await search_files({ pattern: 'ERROR', glob: 'logs/**/*.log' }); Defensive patterns
Strategy: validation
Validate before calling
function isPatternSafe(pattern: string): boolean {
return !pattern.startsWith('/') && !pattern.split('/').includes('..');
}
// Before calling search_files:
if (!isPatternSafe(globPattern)) {
throw new Error(`Pattern "${globPattern}" must be relative and not contain '..'`);
} Type guard
function isPatternEscapeError(e: unknown): boolean {
return e instanceof Error && e.message.startsWith('Pattern "') && e.message.includes('escapes the base directory');
} Prevention
- Use relative glob patterns only (e.g. 'src/**/*.ts')
- Never use leading '/' or '..' segments in search patterns
- Validate patterns with a simple check before passing them to search_files
When it happens
Trigger: A search_files call with a pattern like '/etc/**' (absolute), '../secrets/**' (traversal), or 'src/../../outside/**'. The check splits on '/' and looks for '..' segments, and checks for a leading '/'.
Common situations: Agent constructs a search pattern with an absolute path or with '..' traversal segments, or copies a file path verbatim into the pattern field.
Related errors
- Access denied: "${excludedSegment}" is excluded from filesys
- Invalid skill at ${sourceDirectory}: ${errors.join('; ')}
- File too large: ${stat.size} bytes (max ${MAX_FILE_SIZE} byt
- oldString not found in file: ${filePath}
- Path "${relativePath}" escapes the base directory
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/d728e0dc764dacde.
Report an issue: GitHub.