{"record":{"id":"0e2a594f075b648b","repo":"Yeachan-Heo/oh-my-codex","slug":"refusing-cancellation-because-detached-run-authori","errorCode":null,"errorMessage":"Refusing cancellation because detached run authority is invalid: ${record.run_dir}.","messagePattern":"Refusing cancellation because detached run authority is invalid: (.+?)\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"src/cli/index.ts","lineNumber":8161,"sourceCode":"\n    try {\n      const canonicalRunDir = realpathSync(resolve(record.run_dir));\n      if (!isCanonicalPathWithin(canonicalRunsRoot, canonicalRunDir)) {\n        throw new Error(\"run directory escapes the authorized runs root\");\n      }\n      const stateDir = realpathSync(join(canonicalRunDir, \".omx\", \"state\"));\n      if (!isCanonicalPathWithin(canonicalRunDir, stateDir)) {\n        throw new Error(\"state directory escapes the authorized run directory\");\n      }\n      const session = JSON.parse(await readFile(join(stateDir, \"session.json\"), \"utf-8\")) as Record<string, unknown>;\n      if (session.session_id !== record.session_id) throw new Error(\"run session pointer changed\");\n      const sessionDir = realpathSync(join(stateDir, \"sessions\", record.session_id));\n      if (!isCanonicalPathWithin(stateDir, sessionDir)) {\n        throw new Error(\"session directory escapes the authorized state directory\");\n      }\n      candidates.push({ sessionDir, sessionId: record.session_id, record });\n    } catch (err) {\n      throw new Error(`Refusing cancellation because detached run authority is invalid: ${record.run_dir}.`, { cause: err });\n    }\n  }\n\n  if (candidates.length > 1) throw new Error(\"Refusing cancellation because multiple detached run authorities match.\");\n  if (candidates.length === 0) return null;\n  const [{ sessionDir, sessionId, record }] = candidates;\n  const refs: ModeStateFileRef[] = [];\n  const stateFiles = await readdir(sessionDir).catch(() => [] as string[]);\n  for (const file of stateFiles) {\n    if (!isModeStateFilename(file)) continue;\n    const path = join(sessionDir, file);\n    try {\n      const fileStat = lstatSync(path);\n      if (!fileStat.isFile() || fileStat.isSymbolicLink()) {\n        throw new Error(`Refusing cancellation through non-regular run state target: ${path}.`);\n      }\n      const canonicalFile = realpathSync(path);\n      if (!isCanonicalPathWithin(sessionDir, canonicalFile)) {","sourceCodeStart":8143,"sourceCodeEnd":8179,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/cli/index.ts#L8143-L8179","documentation":"Wrapper around any per-record authority validation failure (213–216 or a read error) during cancellation discovery; it names the offending run_dir and chains the root cause, refusing cancellation for safety.","triggerScenarios":"Any throw inside the try block validating a record's run dir/state/session chain: escaping paths, changed session pointer, unreadable session.json, or missing directories.","commonSituations":"Moved projects/runs roots, symlinked .omx internals, corrupted state after a crash, or permission loss on state files.","solutions":["Read err.cause to identify which specific validation failed and fix that (see the chained error)","Restore/clean the record's run dir state, or delete the invalid detached active record","Re-run cancellation once authority is consistent"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { await cancelDetached(...); } catch (e) {\n  if (/detached run authority is invalid/.test((e as Error).message)) {\n    const cause = (e as Error).cause; // fix the specific 213-216 issue, remove stale record, retry\n  }\n}","preventionTips":["Keep runs root and .omx layout untouched by symlinks","Clean records when moving projects","Cancel by explicit session id to reduce record scanning"],"tags":["security","wrapper-error","cancellation"],"backgroundTag":"path-escapes-allowed-root","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}