{"record":{"id":"5cd791b6408231d5","repo":"JuliusBrussee/caveman","slug":"failed-to-canonicalize-codex-home-json-stringify-configured","errorCode":null,"errorMessage":"failed to canonicalize CODEX_HOME ${JSON.stringify(configured)}: ${(error as Error).message}","messagePattern":"failed to canonicalize CODEX_HOME (.+?): (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cli/src/index.ts","lineNumber":6208,"sourceCode":"  // Match Codex's own home resolver: a nonempty override may be relative, but\n  // must already be a directory and is canonicalized before use. Never fall\n  // back to another account's default home when the override is invalid.\n  let metadata: ReturnType<typeof statSync>;\n  try {\n    metadata = statSync(configured);\n  } catch (error) {\n    if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n      throw new Error(`CODEX_HOME points to ${JSON.stringify(configured)}, but that path does not exist`);\n    }\n    throw new Error(`failed to read CODEX_HOME ${JSON.stringify(configured)}: ${(error as Error).message}`);\n  }\n  if (!metadata.isDirectory()) {\n    throw new Error(`CODEX_HOME points to ${JSON.stringify(configured)}, but that path is not a directory`);\n  }\n  try {\n    return realpathSync(configured);\n  } catch (error) {\n    throw new Error(`failed to canonicalize CODEX_HOME ${JSON.stringify(configured)}: ${(error as Error).message}`);\n  }\n}\n\nfunction codexAuthPath(): string {\n  return join(codexHomeDir(), \"auth.json\");\n}\n\nfunction nonEmptyString(v: unknown): v is string {\n  return typeof v === \"string\" && v.trim().length > 0;\n}\n\nfunction readCodexAuthJson(): JsonObject | undefined {\n  const path = codexAuthPath();\n  try {\n    const stat = statSync(path);\n    if (!stat.isFile() || stat.size === 0) return undefined;\n    const parsed = JSON.parse(readFileSync(path, \"utf8\")) as unknown;\n    return asJsonObject(parsed);","sourceCodeStart":6190,"sourceCodeEnd":6226,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/packages/cli/src/index.ts#L6190-L6226","documentation":"Thrown when realpathSync fails while canonicalizing an existing CODEX_HOME directory (it passed the stat and isDirectory checks). This resolves symlinks to an absolute canonical path; failure here usually means the path became inaccessible between stat and realpath, or a symlink loop / permission issue on a symlinked component.","triggerScenarios":"realpathSync(configured) throws — typically EACCES on a symlink component, ELOOP from a symlink cycle, or ENOENT if the path was deleted between stat and realpath.","commonSituations":"CODEX_HOME containing a self-referencing symlink loop, permissions tightened on ~/.codex or an ancestor after stat, or the directory being concurrently removed.","solutions":["Re-check the path exists and is traversable: `ls -la` on CODEX_HOME and ancestors","Fix symlink loops: inspect with `namei -l \"$CODEX_HOME\"` and remove the cyclic link","Restore read/execute permissions on symlinked directories in the path","Retry; if the directory was concurrently deleted, recreate it with mkdir -p"],"exampleFix":"// before (symlink loop)\nln -s .codex .codex/loop\n// after\nrm .codex/loop && mkdir -p \"$CODEX_HOME\"","handlingStrategy":"try-catch","validationCode":"try { fs.realpathSync(process.env.CODEX_HOME ?? \"\"); } catch (e) { console.error(`CODEX_HOME cannot be canonicalized: ${e.message}`); }","typeGuard":"function isRealCanonicalizableDir(p: string): boolean {\n  try { return fs.statSync(p).isDirectory() && !!fs.realpathSync(p); } catch { return false; }\n}","tryCatchPattern":"try {\n  runCodexCommand();\n} catch (e) {\n  if (String(e.message).startsWith(\"failed to canonicalize CODEX_HOME\")) {\n    console.error(\"Check CODEX_HOME for symlink loops or permission changes: \" + e.message);\n  }\n}","preventionTips":["Avoid symlink loops in CODEX_HOME paths","Keep read/execute permissions stable on symlinked config directories","Use plain absolute directories instead of nested symlink chains for CODEX_HOME"],"tags":["filesystem","symlink","env-var","codex"],"backgroundTag":"file-read-failed","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}