abhigyanpatwari/GitNexus · error · Error
local_path must be normalized and must not contain traversal
Error message
local_path must be normalized and must not contain traversal segments
What it means
normalizeConfiguredCloneRoot rejects local_path values containing a ".." segment, refusing path traversal before resolution. Splitting the raw value on the platform separator and looking for ".." catches traversal attempts regardless of whether resolution would collapse them.
Source
Thrown at gitnexus/src/core/auto-sync/path-security.ts:110
);
assertNotDangerousRoot(realRoot);
assertNotGitNexusInternalRoot(realRoot);
const quarantineRoot = path.join(getAutoSyncWatchDir(), 'quarantine');
await pruneQuarantineEntries(quarantineRoot);
return {
root: realRoot,
quarantineRoot,
quarantineRetentionDays: QUARANTINE_RETENTION_DAYS,
};
}
export function normalizeConfiguredCloneRoot(localPath: string): string {
const value = localPath.trim();
if (!value) throw new Error('local_path is required');
if (!path.isAbsolute(value)) throw new Error('local_path must be an absolute path');
if (value.split(path.sep).includes('..')) {
throw new Error('local_path must be normalized and must not contain traversal segments');
}
const resolved = path.resolve(value);
if (resolved !== path.normalize(value)) {
throw new Error('local_path must be normalized and must not contain traversal segments');
}
return resolved;
}
export async function quarantineAutoSyncPartial(
targetDir: string,
quarantineRoot: string,
): Promise<string> {
await fs.mkdir(quarantineRoot, { recursive: true, mode: 0o700 });
const base = path.basename(targetDir);
const stamp = new Date().toISOString().replace(/[:.]/g, '-');
const destination = path.join(
quarantineRoot,
`auto-sync-${stamp}-${process.pid}-${randomUUID()}-${base}`,View on GitHub (pinned to 0d1aed942f)
Solutions
- Remove the ".." segments and write the direct absolute path to the clone root.
- If the value is assembled from parts, join and clean it in code before assigning local_path.
- Re-run parseAutoSyncConfig to confirm the normalized path is accepted.
Example fix
// before (config) local_path: "/home/user/../srv/clones" // after (config) local_path: "/srv/clones"
Defensive patterns
Strategy: validation
Validate before calling
if (localPath.split(path.sep).includes('..')) throw new Error('local_path must not contain traversal ("..") segments'); Try / catch
try {
parseAutoSyncConfig(raw);
} catch (err) {
if (err.message.includes('must be normalized and must not contain traversal')) {
console.error('Rewrite local_path as a direct absolute path without ".." segments.');
} else throw err;
} Prevention
- Never build local_path from untrusted/user-supplied segments.
- Normalize joined paths in code before persisting them to config.
- Treat ".." in configured paths as a security smell and reject it in review/CI.
When it happens
Trigger: parseAutoSyncConfig receives a local_path with a ".." path segment, e.g. "/home/user/../etc/repos" or "/srv/clones/../../etc".
Common situations: Config values built by concatenation with user input, security-scanning tools flagging traversal-capable paths, or hand-written paths with redundant parent steps.
Understand the failure class
Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.
Related errors
- ${filename} resolves outside the repository root
- path must include owner/repo without traversal
- local_path is required
- local_path must be an absolute path
- Path must not contain null bytes
AI-assisted analysis of abhigyanpatwari/GitNexus@0d1aed942f (2026-09-08).
Data as JSON: /api/errors/c767543ff3fb90af.
Report an issue: GitHub.