Yeachan-Heo/oh-my-codex · error · Error
sendToWorker: failed to send text: ${send.stderr}
Error message
sendToWorker: failed to send text: ${send.stderr} What it means
Thrown when the tmux `send-keys -l` command used to deliver literal text to a worker pane exits non-zero. The error wraps tmux's own stderr, so the underlying cause is a tmux-level failure such as a dead/missing target pane, a detached session, or tmux not being installed. This is a process-spawn failure, not a validation error.
Source
Thrown at src/team/tmux-session.ts:3452
if (strategy !== 'auto') return false;
if (!paneBusyAtStart) return false;
if (typeof latestCapture !== 'string') return false;
const normalizedText = normalizeWorkerTriggerForDraftMatch(text);
if (normalizedText === '') return false;
const normalizedCapture = normalizeWorkerTriggerForDraftMatch(latestCapture);
if (!normalizedCapture.includes(normalizedText)) return false;
if (paneHasActiveTask(latestCapture)) return false;
if (!paneLooksReady(latestCapture)) return false;
return true;
}
async function sendLiteralTextOrThrow(resolveTarget: AsyncPaneTargetResolver, text: string): Promise<void> {
const target = await requireAsyncPaneTarget(resolveTarget);
const send = await runTmuxAsync(['send-keys', '-t', target, '-l', '--', text]);
if (!send.ok) {
throw new Error(`sendToWorker: failed to send text: ${send.stderr}`);
}
}
function paneHasQueuedCodexSubmission(captured: string | null | undefined): boolean {
const normalized = normalizeTmuxCapture(captured ?? '');
if (normalized === '') return false;
return /messages to be submitted after next tool call/i.test(normalized)
|| /press esc to interrupt and send immediately/i.test(normalized);
}
async function attemptSubmitRounds(
resolveTarget: AsyncPaneTargetResolver,
text: string,
rounds: number,
queueFirstRound: boolean,
submitKeyPressesPerRound: number,
): Promise<boolean> {
const presses = Math.max(1, Math.floor(submitKeyPressesPerRound));View on GitHub (pinned to 3ad79a8a6f)
Solutions
- Check send.stderr in the message: 'no such pane'/'can't find session' means the pane/session is gone — recreate the worker pane and retry
- Verify tmux is installed and the tmux server is running: `tmux ls`
- Re-resolve the pane target (list-panes) instead of reusing a cached pane id
- If panes are frequently closing, review worker startup/keepalive logic
Example fix
// before
await sendLiteralTextOrThrow(resolveTarget, text);
// after
try {
await sendLiteralTextOrThrow(resolveTarget, text);
} catch (err) {
// pane may be gone: re-resolve or respawn worker
await respawnWorkerPane();
await sendLiteralTextOrThrow(freshResolveTarget, text);
} Defensive patterns
Strategy: retry
Validate before calling
const panes = await runTmuxAsync(['list-panes', '-a', '-F', '#{pane_id}']);
if (!panes.ok || !panes.stdout.includes(targetPaneId)) {
await respawnWorkerPane();
} Try / catch
try { await sendLiteralTextOrThrow(resolveTarget, text); } catch (err) { if (/failed to send text/.test(String(err))) { await respawnWorkerPane(); await sendLiteralTextOrThrow(freshTarget, text); } else throw err; } Prevention
- Re-resolve pane targets immediately before each send
- Watch the worker pane for close events and stop sending
- Verify tmux availability with isTmuxAvailable() before operations
When it happens
Trigger: Calling sendLiteralTextOrThrow (or a higher-level sendToWorker path) after the target pane was closed, the tmux server was killed, the session name no longer resolves, or the tmux binary is missing from PATH (runTmuxAsync fails). Also occurs when the resolveTarget pane id becomes stale between resolution and send.
Common situations: Worker pane closed by the agent or user mid-run; tmux server restarted; SSH session dropped taking the tmux server with it; stale pane id cached from a previous run; tmux not installed in CI containers.
Related errors
- sendToWorker: text must be < 200 characters
- sendToWorker: text must be non-empty
- sendToWorker: injection marker is not allowed
- invalid auth slot path
- auth directory must not be a symlink: ${dir}
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/600e6d63c078fda1.
Report an issue: GitHub.