Yeachan-Heo/oh-my-codex · error · Error

${label} must not be a symlink: ${path}

Error message

${label} must not be a symlink: ${path}

What it means

The worker-pane proof reader returns 'unavailable' with a reason starting 'pane_id_changed:' when the pane id no longer resolves to the same underlying pane. The library converts this into an explicit 'identity changed' error rather than a generic unavailability, because id churn means the pinned worker no longer exists as such.

Source

Thrown at src/auth/paths.ts:81

}

export async function assertReadableFile(path: string, label: string): Promise<void> {
  try {
    const info = await stat(path);
    if (!info.isFile()) throw new Error(`${label} is not a file: ${path}`);
  } catch (err) {
    if (err && typeof err === "object" && "code" in err && err.code === "ENOENT") {
      throw new Error(`${label} not found: ${path}`);
    }
    throw err;
  }
}

export async function assertNoSymlink(path: string, label: string): Promise<void> {
  try {
    const { lstat } = await import("fs/promises");
    const info = await lstat(path);
    if (info.isSymbolicLink()) throw new Error(`${label} must not be a symlink: ${path}`);
  } catch (err) {
    if (err && typeof err === "object" && "code" in err && err.code === "ENOENT") return;
    throw err;
  }
}

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. Re-resolve the worker pane from a fresh split instead of reusing a persisted pane id
  2. Recreate the team session after tmux server restarts
  3. Inspect proof.reason after 'pane_id_changed:' for the old/new id detail
  4. Prevent other orchestrators from killing team panes
Defensive patterns

Strategy: fallback

Validate before calling

const proof = readExactWorkerPaneLivenessProofSync(workerPaneId); if (proof.status === 'unavailable' && proof.reason.startsWith('pane_id_changed:')) planRelaunch();

Try / catch

catch (err) { if (/worker pane identity changed/.test(err.message)) { relaunchWorkerPane(); } }

Prevention

When it happens

Trigger: Calling worker-pane resolution when the worker pane id was recycled — pane killed and id reused, session restarted with leftover ids, or window layout changes reassigning pane ids.

Common situations: Persisting worker pane ids across restarts, respawn flows, or concurrent sessions on one tmux server churning pane ids.

Related errors


AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27). Data as JSON: /api/errors/2d7cc2fa24a5afb4. Report an issue: GitHub.