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

unsupported_session_kind

unsupported_session_kind

Error message

unsupported_session_kind:invalid_tmux_pane_binding:${tmuxSessionName}

What it means

The Hermes bridge can deliver prompts to a session bound to a tmux pane, but only if the recorded tmux_pane_id is a syntactically valid pane id. If the stored binding fails isTmuxPaneId, delivery is refused with this unsupported_session_kind error rather than sending keys to an arbitrary target.

Source

Thrown at src/mcp/hermes-bridge.ts:207

    encoding: "utf-8",
    stdio: ["ignore", "pipe", "pipe"],
    windowsHide: process.platform === "win32",
  });
}

async function sendPromptToBoundTmuxSession(
  cwd: string,
  sessionId: string,
  prompt: string,
  deps: HermesBridgeDeps,
): Promise<HermesTmuxPromptResult | null> {
  const rawSession = await readSessionState(cwd);
  if (!rawSession || !sessionMatchesRequested(rawSession, sessionId)) return null;
  const tmuxSessionName = optionalString(rawSession.tmux_session_name);
  const tmuxPaneId = optionalString(rawSession.tmux_pane_id);
  if (!tmuxSessionName || !tmuxPaneId) return null;
  if (!isTmuxPaneId(tmuxPaneId)) {
    throw new Error(`unsupported_session_kind:invalid_tmux_pane_binding:${tmuxSessionName}`);
  }

  const execTmux = deps.execTmuxFileSync ?? defaultExecTmuxFileSync;
  try {
    execTmux(["has-session", "-t", tmuxSessionName]);
    const instanceId = String(execTmux(["show-options", "-qv", "-t", tmuxSessionName, OMX_INSTANCE_OPTION]) ?? "").trim();
    if (instanceId !== rawSession.session_id) {
      throw new Error(`tmux_instance_mismatch:${tmuxSessionName}:${instanceId || "missing"}`);
    }
    const paneSession = String(execTmux(["display-message", "-p", "-t", tmuxPaneId, "#{session_name}"]) ?? "").trim();
    if (paneSession !== tmuxSessionName) {
      throw new Error(`pane_session_mismatch:${tmuxPaneId}:${paneSession || "missing"}`);
    }
    for (const argv of buildSendPaneArgvs(tmuxPaneId, prompt, true)) {
      execTmux(argv);
    }
  } catch (error) {
    const message = errorMessage(error);

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. Inspect the session state file's tmux_pane_id and fix it to a real pane id like %3
  2. Restart the session so it rebinds to a fresh tmux pane
  3. Delete stale session state for dead sessions
Defensive patterns

Strategy: validation

Validate before calling

const PANE = /^%\d+$/; // typical tmux pane id shape
if (state.tmux_session_name && !PANE.test(state.tmux_pane_id ?? '')) { /* rebind session before sending */ }

Type guard

function hasValidPaneBinding(s: SessionState): boolean { return typeof s.tmux_session_name === 'string' && /^%\d+$/.test(s.tmux_pane_id ?? ''); }

Try / catch

catch (e) { if ((e as Error).message.startsWith('unsupported_session_kind:invalid_tmux_pane_binding')) { /* restart/rebind session */ } }

Prevention

When it happens

Trigger: sendPromptToBoundTmuxSession reads session state with tmux_session_name set but tmux_pane_id not matching the pane-id format (e.g. '%0x' garbage, an empty-ish string, or a window id like '@3').

Common situations: Session state written by an older version or corrupted, manual edits to the state file, or a tmux binding recorded from a non-pane target.

Related errors


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