stablyai/orca · error · Error

Legacy rollout source is not a regular file.

Error message

Legacy rollout source is not a regular file.

What it means

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.

Source

Thrown at src/main/codex/codex-legacy-session-resume.ts:135

  }
  const candidatePath = join(selectedCodexHome, 'sessions', relativePath)
  try {
    const candidateStat = await lstat(candidatePath)
    // Why: the bridge is async, so an unbridged rollout is a real state — decline rather than pin a home codex cannot resume from.
    return candidateStat.isFile() && !candidateStat.isSymbolicLink() ? selectedCodexHome : null
  } catch {
    return null
  }
}

async function materializeLegacyRollout(
  sourcePath: string,
  targetPath: string,
  auditLogPath: string
): Promise<void> {
  const sourceStat = await lstat(sourcePath)
  if (!sourceStat.isFile() || sourceStat.isSymbolicLink()) {
    throw new Error('Legacy rollout source is not a regular file.')
  }
  await mkdir(dirname(targetPath), { recursive: true })
  try {
    await link(sourcePath, targetPath)
  } catch (linkError) {
    if (isExistsError(linkError)) {
      await assertMatchingExistingTarget(sourcePath, targetPath)
    } else {
      try {
        await copySessionFileWithoutOverwrite(sourcePath, targetPath)
      } catch (copyError) {
        if (isExistsError(copyError)) {
          await assertMatchingExistingTarget(sourcePath, targetPath)
        } else {
          if (isAtomicNoReplaceUnsupportedError(copyError)) {
            throw new Error('The target filesystem cannot safely install this rollout.', {
              cause: copyError
            })

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Check the file type: ls -la <sourcePath> (look for leading 'd' or 'l').
  2. If it's a symlink, replace it with the real file (cp -L) or remove it and let codex regenerate.
  3. If it's a directory, the path is wrong — locate the actual rollout file.
  4. Restore the rollout from a backup as a regular file.
Defensive patterns

Strategy: validation

Validate before calling

import { lstat } from 'node:fs/promises'
const st = await lstat(sourcePath)
if (!st.isFile() || st.isSymbolicLink()) {
  // decline to resume; the source must be a regular file
}

Try / catch

try {
  await prepareLegacySharedCodexSessionResume(args, options)
} catch (error) {
  if (error instanceof Error && error.message === 'Legacy rollout source is not a regular file.') {
    // alert user: source is a symlink/dir; cannot relocate
  } else throw error
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12). Data as JSON: /api/errors/aab06c6627909045. Report an issue: GitHub.