Yeachan-Heo/oh-my-codex · error · Error
Refusing cancellation outside authorized state root: ${ref.p
Error message
Refusing cancellation outside authorized state root: ${ref.path}. What it means
After canonicalizing each state target with realpath, the cancel command verifies both the file and its parent directory resolve inside the authorized state root. If either escapes that root (via symlinked parents, ../ segments, or bind mounts), cancellation refuses with this error. This is a path-containment security check preventing writes outside authorized state boundaries.
Source
Thrown at src/cli/index.ts:8413
dev: number;
ino: number;
}
>();
if (refs.length === 0) return loaded;
const canonicalAuthorityRoot = assertCancellationAuthorityPath(
authorityRoot === writableScope.stateDir ? baseStateDir : authorityRoot,
authorityRoot,
);
for (const ref of refs) {
const fileStat = lstatSync(ref.path);
if (!fileStat.isFile() || fileStat.isSymbolicLink()) {
throw new Error(`Refusing cancellation through non-regular state target ${ref.path}.`);
}
const canonicalPath = realpathSync(ref.path);
const canonicalParent = realpathSync(dirname(ref.path));
if (!isCanonicalPathWithin(canonicalAuthorityRoot, canonicalParent, true)
|| !isCanonicalPathWithin(canonicalAuthorityRoot, canonicalPath)) {
throw new Error(`Refusing cancellation outside authorized state root: ${ref.path}.`);
}
const content = await readFile(canonicalPath, "utf-8");
let parsedState: Record<string, unknown>;
try {
const parsed = JSON.parse(content) as unknown;
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
throw new Error("state must be a JSON object");
}
parsedState = parsed as Record<string, unknown>;
} catch (err) {
logCliOperationFailure(err);
throw new Error(`Refusing partial cancellation because ${ref.path} is malformed.`, { cause: err });
}
if (typeof parsedState.mode === "string" && parsedState.mode !== ref.mode) {
throw new Error(`Refusing contradictory mode state in ${ref.path}.`);
}
if (ref.mode === SKILL_ACTIVE_STATE_MODE && exactAuthority) {
const hasTopCodexOwner = Object.prototype.hasOwnProperty.call(parsedState, "owner_codex_session_id");View on GitHub (pinned to 3ad79a8a6f)
Solutions
- Check whether any component of the referenced state path is a symlink and replace it with its real location
- Ensure the configured state directory's realpath matches what the authority root expects
- Re-run cancel from the workspace root so the state scope resolves canonically
- Remove stale symlinked parents and use direct paths
Example fix
# before ~/.omx -> /mnt/shared/omx (parent symlink escapes root) # after mv /mnt/shared/omx ~/.omx (real directory inside expected root)
Defensive patterns
Strategy: validation
Validate before calling
import { realpathSync, dirname } from "node:fs";
import { isAbsolute, relative } from "node:path";
function pathWithinRoot(path: string, root: string): boolean {
const rel = relative(realpathSync(root), realpathSync(path));
return rel !== "" && !rel.startsWith("..") && !isAbsolute(rel);
} Type guard
function isCanonicalPathWithin(root: string, target: string): boolean {
const rel = relative(realpathSync(root), realpathSync(target));
return rel === "" || (!rel.startsWith("..") && !isAbsolute(rel));
} Prevention
- Keep the entire state path free of symlinks
- Run cancel from the workspace root so scope resolution is canonical
- Verify realpath(configuredStateDir) matches expectations in containerized setups
When it happens
Trigger: A state path whose canonical resolution lands outside the authority root: a parent directory that is a symlink to elsewhere, a path containing .. that escapes, or the file itself being a link to a file in another tree.
Common situations: State directory or its parents symlinked (common in dotfiles or multi-project setups); misconfigured stateDir pointing at a path whose realpath differs; running inside containers with overlapping mounts; moved project directories where realpath differs from the configured path.
Related errors
- Refusing cancellation through non-regular state target ${ref
- Refusing to back up ${artifact.path} outside controlled back
- mode must not contain ".."
- fileName must not contain ".."
- run directory escapes the authorized runs root
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/ef33ed759d2275a6.
Report an issue: GitHub.