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

  1. Remove the ".." segments and write the direct absolute path to the clone root.
  2. If the value is assembled from parts, join and clean it in code before assigning local_path.
  3. 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

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


AI-assisted analysis of abhigyanpatwari/GitNexus@0d1aed942f (2026-09-08). Data as JSON: /api/errors/c767543ff3fb90af. Report an issue: GitHub.