{"record":{"id":"aab06c6627909045","repo":"stablyai/orca","slug":"legacy-rollout-source-is-not-a-regular-file","errorCode":null,"errorMessage":"Legacy rollout source is not a regular file.","messagePattern":"Legacy rollout source is not a regular file\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/main/codex/codex-legacy-session-resume.ts","lineNumber":135,"sourceCode":"  }\n  const candidatePath = join(selectedCodexHome, 'sessions', relativePath)\n  try {\n    const candidateStat = await lstat(candidatePath)\n    // Why: the bridge is async, so an unbridged rollout is a real state — decline rather than pin a home codex cannot resume from.\n    return candidateStat.isFile() && !candidateStat.isSymbolicLink() ? selectedCodexHome : null\n  } catch {\n    return null\n  }\n}\n\nasync function materializeLegacyRollout(\n  sourcePath: string,\n  targetPath: string,\n  auditLogPath: string\n): Promise<void> {\n  const sourceStat = await lstat(sourcePath)\n  if (!sourceStat.isFile() || sourceStat.isSymbolicLink()) {\n    throw new Error('Legacy rollout source is not a regular file.')\n  }\n  await mkdir(dirname(targetPath), { recursive: true })\n  try {\n    await link(sourcePath, targetPath)\n  } catch (linkError) {\n    if (isExistsError(linkError)) {\n      await assertMatchingExistingTarget(sourcePath, targetPath)\n    } else {\n      try {\n        await copySessionFileWithoutOverwrite(sourcePath, targetPath)\n      } catch (copyError) {\n        if (isExistsError(copyError)) {\n          await assertMatchingExistingTarget(sourcePath, targetPath)\n        } else {\n          if (isAtomicNoReplaceUnsupportedError(copyError)) {\n            throw new Error('The target filesystem cannot safely install this rollout.', {\n              cause: copyError\n            })","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/codex/codex-legacy-session-resume.ts#L117-L153","documentation":"Thrown by materializeLegacyRollout when lstat(sourcePath) shows the source is not a regular file — it's a directory, socket, device, or a symbolic link. Orca only relocates regular rollout files; symlinks are explicitly excluded to avoid crossing trust boundaries or pulling in dangling links.","triggerScenarios":"sourcePath resolves to a directory; sourcePath is a symlink (even to a regular file, it's rejected); the rollout path points at a socket/FIFO/device; lstat succeeded but isFile() is false or isSymbolicLink() is true.","commonSituations":"A user replaced a rollout file with a symlink; the sessions root got a directory named like a rollout; filesystem corruption returned an odd mode; a backup tool converted files to symlinks.","solutions":["Check the file type: ls -la <sourcePath> (look for leading 'd' or 'l').","If it's a symlink, replace it with the real file (cp -L) or remove it and let codex regenerate.","If it's a directory, the path is wrong — locate the actual rollout file.","Restore the rollout from a backup as a regular file."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import { lstat } from 'node:fs/promises'\nconst st = await lstat(sourcePath)\nif (!st.isFile() || st.isSymbolicLink()) {\n  // decline to resume; the source must be a regular file\n}","typeGuard":null,"tryCatchPattern":"try {\n  await prepareLegacySharedCodexSessionResume(args, options)\n} catch (error) {\n  if (error instanceof Error && error.message === 'Legacy rollout source is not a regular file.') {\n    // alert user: source is a symlink/dir; cannot relocate\n  } else throw error\n}","preventionTips":["Don't replace rollout files with symlinks.","Validate the source is a regular file before resume.","If a symlink is needed, dereference it and replace with the target regular file.","Audit backup tools that convert files to symlink stubs."],"tags":["codex","session-resume","legacy","filesystem","symlink","path-validation"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}