Yeachan-Heo/oh-my-codex · critical · Error
scale_down_cleanup_debt_path_escape:${path}
Error message
scale_down_cleanup_debt_path_escape:${path} What it means
The closest existing ancestor of a scale-down cleanup path resolves (via realpath) outside the allowed root, so cleanup would touch paths escaping the team/repo root. The message embeds the path.
Source
Thrown at src/team/scaling.ts:1552
): boolean {
const relativePath = pathSemantics.relative(root, path);
return relativePath === ''
|| (!pathSemantics.isAbsolute(relativePath)
&& relativePath !== '..'
&& !relativePath.startsWith(`..${pathSemantics.sep}`));
}
async function assertExistingPathParentContained(path: string, root: string): Promise<void> {
const canonicalRoot = await realpath(root);
let candidate = resolve(path);
while (!existsSync(candidate)) {
const parent = dirname(candidate);
if (parent === candidate) throw new Error(`scale_down_cleanup_debt_path_missing_parent:${path}`);
candidate = parent;
}
const canonicalExistingPath = await realpath(candidate);
if (!isSameOrInsidePath(canonicalExistingPath, canonicalRoot)) {
throw new Error(`scale_down_cleanup_debt_path_escape:${path}`);
}
}
async function validateScaleDownCleanupResources(
teamName: string,
leaderCwd: string,
teamStateRoot: string,
workers: readonly ScaleDownCleanupDebtResource[],
): Promise<void> {
const canonicalLeaderCwd = await realpath(leaderCwd);
let repoRoot = canonicalLeaderCwd;
const repoRootResult = spawnSync('git', ['rev-parse', '--show-toplevel'], {
cwd: leaderCwd,
encoding: 'utf-8',
windowsHide: true,
});
const reportedRepoRoot = (repoRootResult.stdout || '').trim();
if (repoRootResult.status === 0 && reportedRepoRoot) {View on GitHub (pinned to 3ad79a8a6f)
Solutions
- Remove or fix symlinks in the team state / worktree paths so they resolve inside the root
- Update worker records in team config with correct absolute paths under the team state root
- Re-run scale-down after normalizing paths
Defensive patterns
Strategy: validation
Validate before calling
import { realpathSync } from 'node:fs';
import { resolve, sep } from 'node:path';
function resolvesWithin(p: string, root: string): boolean {
let cur = p;
while (!existsSync(cur)) cur = dirname(cur);
const real = realpathSync(cur);
return real === root || real.startsWith(root + sep);
} Try / catch
catch (e) {
if ((e as Error).message.startsWith('scale_down_cleanup_debt_path_escape')) {
throw new Error('cleanup path escapes root: fix symlinks in team state paths');
}
throw e;
} Prevention
- Never symlink team state or worktree directories to other volumes
- Audit worker metadata paths after moving repos between machines
When it happens
Trigger: assertExistingPathParentContained finds an existing ancestor whose realpath is not inside the canonical root, e.g. the path traverses a symlink pointing outside the root.
Common situations: Symlinked team state directory pointing elsewhere on disk; worker metadata with crafted relative/absolute paths attempting traversal; moved repo where stale absolute paths now resolve outside the root.
Related errors
- scale_down_cleanup_debt_worktree_symlink:${worker.name}
- run directory escapes the authorized runs root
- state directory escapes the authorized run directory
- session directory escapes the authorized state directory
- Path traversal detected: path is outside the allowed directo
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/61ad191bed632fbb.
Report an issue: GitHub.