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

  1. Remove or fix symlinks in the team state / worktree paths so they resolve inside the root
  2. Update worker records in team config with correct absolute paths under the team state root
  3. 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

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


AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27). Data as JSON: /api/errors/61ad191bed632fbb. Report an issue: GitHub.