Yeachan-Heo/oh-my-codex · error
tmux is unavailable; omx question requires tmux for OMX-owne
Error message
tmux is unavailable; omx question requires tmux for OMX-owned question UI rendering.
What it means
defaultExecTmux resolves the tmux binary per platform (resolveTmuxBinaryForPlatform) before every tmux invocation; when no binary can be found (tmux absent on PATH, or the Windows psmux shim missing), it throws immediately. OMX-owned question UI rendering is tmux-based, so tmux is a hard requirement, not optional.
Source
Thrown at src/question/renderer.ts:503
}
sleepImpl(QUESTION_TEXT_SETTLE_MS);
execTmux(['send-keys', '-t', paneId, 'C-m']);
return {
renderer: 'tmux-pane',
target: paneId,
launched_at: options.launchedAt,
...(options.returnTarget ? { return_target: options.returnTarget, return_transport: 'tmux-send-keys' as const } : {}),
};
}
function defaultSpawnDetachedRenderer(command: string, args: string[], options: SpawnOptions): Pick<ChildProcess, 'pid' | 'unref'> {
return spawn(command, args, options);
}
function defaultExecTmux(args: string[]): string {
const tmux = resolveTmuxBinaryForPlatform();
if (!tmux) throw new Error('tmux is unavailable; omx question requires tmux for OMX-owned question UI rendering.');
return execFileSync(tmux, args, {
encoding: 'utf-8',
...(process.platform === 'win32' ? { windowsHide: true } : {}),
});
}
function readJsonFileIfExists(path: string): Record<string, unknown> | null {
if (!existsSync(path)) return null;
try {
const parsed = JSON.parse(readFileSync(path, 'utf-8')) as unknown;
return parsed && typeof parsed === 'object' && !Array.isArray(parsed)
? parsed as Record<string, unknown>
: null;
} catch {
return null;
}
}
View on GitHub (pinned to 3ad79a8a6f)
Solutions
- Install tmux (`apt-get install tmux`, `brew install tmux`) or on Windows install the psmux/wintmux shim.
- Ensure tmux is on PATH for the process environment (echo process.env.PATH from your host).
- Pre-check availability with resolveTmuxBinaryForPlatform or `tmux -V` before launching the question UI.
Defensive patterns
Strategy: validation
Validate before calling
import { execFileSync } from 'node:child_process';
function tmuxAvailable(): boolean {
try { execFileSync(process.platform === 'win32' ? 'psmux' : 'tmux', ['-V']); return true; } catch { return false; }
} Try / catch
try { launchQuestionRenderer(opts); } catch (e) { if (e instanceof Error && /tmux is unavailable/.test(e.message)) { /* degrade to non-interactive question mode */ } else throw e; } Prevention
- Install tmux (or the Windows shim) in CI/Docker images.
- PATH-check for tmux in deployment scripts.
- Use headless question modes where tmux cannot be guaranteed.
When it happens
Trigger: Calling launchQuestionRenderer (or any code path that shells out to tmux, e.g. supersedeLiveQuestionsForSession) on a machine without tmux installed; PATH stripped in the execution environment; Windows without the psmux/wintmux shim.
Common situations: Docker containers/CI images without tmux; SSH sessions where PATH differs; macOS/Linux minimal installs; Windows hosts missing the bundled shim.
Related errors
- [sparkshell] raw fallback failed: executable not found (${in
- omx question cannot open a visible renderer because this pro
- Team mode requires running inside tmux current leader pane
- tmux_session_query_unavailable
- invalid auth slot path
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/23add392549b15bd.
Report an issue: GitHub.