Yeachan-Heo/oh-my-codex · critical · Error
run directory escapes the authorized runs root
Error message
run directory escapes the authorized runs root
What it means
While collecting detached run authorities for cancellation, realpath(record.run_dir) resolves outside the authorized runs root, so the record is considered untrusted and refused.
Source
Thrown at src/cli/index.ts:8147
const candidates: Array<{ sessionDir: string; sessionId: string; record: MadmaxDetachedActiveRecord }> = [];
const files = await readdir(activeDir).catch(() => [] as string[]);
for (const file of files) {
if (!file.endsWith(".json")) continue;
const record = readMadmaxDetachedActiveRecord(join(activeDir, file));
if (!record || file !== `${record.context_key}.json`) continue;
if (!record.session_id || normalizeSessionId(record.session_id) !== record.session_id) continue;
if (!hasMatchingMadmaxDetachedRuntimeBinding(record)) continue;
if (
canonicalizePathForRunDirMatch(record.source_cwd) !== canonicalCwd
&& (!record.worktree_cwd || canonicalizePathForRunDirMatch(record.worktree_cwd) !== canonicalCwd)
) continue;
try {
const canonicalRunDir = realpathSync(resolve(record.run_dir));
if (!isCanonicalPathWithin(canonicalRunsRoot, canonicalRunDir)) {
throw new Error("run directory escapes the authorized runs root");
}
const stateDir = realpathSync(join(canonicalRunDir, ".omx", "state"));
if (!isCanonicalPathWithin(canonicalRunDir, stateDir)) {
throw new Error("state directory escapes the authorized run directory");
}
const session = JSON.parse(await readFile(join(stateDir, "session.json"), "utf-8")) as Record<string, unknown>;
if (session.session_id !== record.session_id) throw new Error("run session pointer changed");
const sessionDir = realpathSync(join(stateDir, "sessions", record.session_id));
if (!isCanonicalPathWithin(stateDir, sessionDir)) {
throw new Error("session directory escapes the authorized state directory");
}
candidates.push({ sessionDir, sessionId: record.session_id, record });
} catch (err) {
throw new Error(`Refusing cancellation because detached run authority is invalid: ${record.run_dir}.`, { cause: err });
}
}
if (candidates.length > 1) throw new Error("Refusing cancellation because multiple detached run authorities match.");View on GitHub (pinned to 3ad79a8a6f)
Solutions
- Correct record.run_dir in the detached active record to point inside the current runs root
- Remove the stale active record and re-register/re-launch the session
- Ensure OMX_ROOT is set consistently between launch and cancel
Defensive patterns
Strategy: validation
Validate before calling
const real = realpathSync(resolve(record.run_dir));
if (!real.startsWith(realpathSync(runsRoot) + sep)) throw new Error('run_dir outside runs root — fix record'); Prevention
- Set OMX_ROOT identically at launch and cancel time
- Never symlink run dirs outside the runs root
- Clean active records when relocating projects
When it happens
Trigger: record.run_dir is a symlink whose real path is outside canonicalRunsRoot, or OMX_ROOT/runs root was moved/changed since the record was written (relative run_dir resolving elsewhere).
Common situations: The project or runs root was relocated, a symlinked workspace, or a hand-edited active-record JSON pointing run_dir at an arbitrary path.
Related errors
- state directory escapes the authorized run directory
- session directory escapes the authorized state directory
- scale_down_cleanup_debt_path_escape:${path}
- Refusing cancellation through non-regular run state target:
- Refusing cancellation through non-regular state target ${ref
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/23a34389ad3fb108.
Report an issue: GitHub.