{"record":{"id":"58149d7c3b8ff6d4","repo":"Yeachan-Heo/oh-my-codex","slug":"label-is-not-a-file-path","errorCode":null,"errorMessage":"${label} is not a file: ${path}","messagePattern":"(.+?) is not a file: (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/auth/paths.ts","lineNumber":68,"sourceCode":"  const codexHome = resolveCodexHomeForLaunch(cwd, env) || resolveDefaultCodexHome(home);\n  return join(codexHome, \"auth.json\");\n}\n\nexport async function ensurePrivateDir(dir: string): Promise<void> {\n  await mkdir(dir, { recursive: true, mode: AUTH_DIR_MODE });\n  const info = await lstat(dir);\n  if (info.isSymbolicLink()) throw new Error(`auth directory must not be a symlink: ${dir}`);\n  if (!info.isDirectory()) throw new Error(`auth path is not a directory: ${dir}`);\n  if (process.platform !== \"win32\") {\n    const { chmod } = await import(\"fs/promises\");\n    await chmod(dir, AUTH_DIR_MODE).catch(() => undefined);\n  }\n}\n\nexport async function assertReadableFile(path: string, label: string): Promise<void> {\n  try {\n    const info = await stat(path);\n    if (!info.isFile()) throw new Error(`${label} is not a file: ${path}`);\n  } catch (err) {\n    if (err && typeof err === \"object\" && \"code\" in err && err.code === \"ENOENT\") {\n      throw new Error(`${label} not found: ${path}`);\n    }\n    throw err;\n  }\n}\n\nexport async function assertNoSymlink(path: string, label: string): Promise<void> {\n  try {\n    const { lstat } = await import(\"fs/promises\");\n    const info = await lstat(path);\n    if (info.isSymbolicLink()) throw new Error(`${label} must not be a symlink: ${path}`);\n  } catch (err) {\n    if (err && typeof err === \"object\" && \"code\" in err && err.code === \"ENOENT\") return;\n    throw err;\n  }\n}","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/auth/paths.ts#L50-L86","documentation":"requireFrozenWindowTopologySync ends with a second full topology read (listPanesResult) to confirm the pane set didn't change during validation. If that final `tmux list-panes` fails, this error wraps the tmux failure — validation cannot conclude.","triggerScenarios":"The session or tmux server dying between the first and final topology reads within one validation call, or transient tmux command failure under load.","commonSituations":"Session killed externally mid-operation, tmux server restart, or socket issues.","solutions":["Check `tmux has-session -t <name>`; recreate the team session if gone","Read the embedded error text for the tmux stderr cause","Retry the guarded operation once if the session is confirmed alive","Avoid running tmux kill-server / session cleanup concurrently with guarded operations"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"runTmuxOk(['has-session', '-t', teamTarget]);","typeGuard":null,"tryCatchPattern":"catch (err) { if (/failed to read tmux pane topology/.test(err.message)) { if (sessionAlive) retryOnce(); else rebuildTeamSession(); } }","preventionTips":["No concurrent kill-server/session cleanup","Health-check the session before guarded calls","Read embedded stderr for root cause"],"tags":["tmux","session-not-found","topology","race-condition"],"backgroundTag":"tmux-session-not-found","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}