{"record":{"id":"a346d7386c6bc428","repo":"Yeachan-Heo/oh-my-codex","slug":"sendtoworker-submit-queued-after-tool-call","errorCode":null,"errorMessage":"sendToWorker: submit_queued_after_tool_call","messagePattern":"sendToWorker: submit_queued_after_tool_call","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"src/team/tmux-session.ts","lineNumber":3870,"sourceCode":"  const [verifyCapture, verifyVisibleCapture] = await Promise.all([\n    capturePaneAsync(resolveTarget),\n    captureVisiblePaneAsync(resolveTarget),\n  ]);\n  if (verifyCapture) {\n    if (paneHasActiveTask(verifyCapture)) return;\n    if (\n      !normalizeWorkerTriggerForDraftMatch(verifyCapture).includes(normalizeWorkerTriggerForDraftMatch(text))\n      && !paneHasQueuedCodexSubmission(verifyVisibleCapture)\n    ) {\n      return;\n    }\n    // Draft still visible and no active task — one more Enter attempt.\n    await sendKeyAsync(resolveTarget, 'Enter');\n    await sleep(150);\n    await sendKeyAsync(resolveTarget, 'Enter');\n    const finalVisibleCapture = await captureVisiblePaneAsync(resolveTarget);\n    if (paneHasQueuedCodexSubmission(finalVisibleCapture)) {\n      throw new Error('sendToWorker: submit_queued_after_tool_call');\n    }\n    const finalCapture = await capturePaneAsync(resolveTarget);\n    if (\n      normalizeWorkerTriggerForDraftMatch(finalCapture).includes(normalizeWorkerTriggerForDraftMatch(text))\n      && !paneHasActiveTask(finalCapture)\n      && paneLooksReady(finalCapture)\n    ) {\n      throw new Error('sendToWorker: submit_failed (trigger text still visible after retries)');\n    }\n  }\n}\n\nexport function notifyLeaderStatus(sessionName: string, message: string): boolean {\n  if (!isTmuxAvailable()) return false;\n  const trimmed = message.trim();\n  if (!trimmed) return false;\n  const capped = trimmed.length > 180 ? `${trimmed.slice(0, 177)}...` : trimmed;\n  const result = runTmux(['display-message', '-t', sessionName, '--', capped]);","sourceCodeStart":3852,"sourceCodeEnd":3888,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/team/tmux-session.ts#L3852-L3888","documentation":"After a tool call, the worker's draft line was still queued rather than executed: the pane capture still matches paneHasQueuedCodexSubmission after a final double-Enter attempt. The submission is stuck behind the worker's post-tool-call state, so the library reports submit_queued_after_tool_call instead of silently assuming success.","triggerScenarios":"Sending a trigger while the worker is finishing a tool call; the Enter presses get buffered as a queued Codex submission; final capture still shows the queued draft line, so the error is thrown.","commonSituations":"Race between tool-call completion and user/leader input; pressing Enter during Codex's spinner state; slow tool execution (npm install, test run) where keystrokes queue up.","solutions":["Wait until the pane shows an idle prompt (paneLooksReady / no active task) before submitting","Retry the whole submit after a delay once the tool call finishes","Avoid sending triggers while paneHasActiveTask is true"],"exampleFix":"// before\nawait sendToWorker(resolveTarget, text); // during tool call\n\n// after\nawait waitFor(async () => paneLooksReady(await capturePaneAsync(resolveTarget)));\nawait sendToWorker(resolveTarget, text);","handlingStrategy":"retry","validationCode":"const cap = await capturePaneAsync(resolveTarget);\nif (paneHasActiveTask(cap)) await waitForWorkerIdle(resolveTarget);","typeGuard":null,"tryCatchPattern":"try { await submitWorker(resolveTarget, text); } catch (err) { if (!/submit_queued_after_tool_call/.test(String(err))) throw err; await sleep(1500); await submitWorker(resolveTarget, text); }","preventionTips":["Never send triggers while a tool call is running","Poll paneLooksReady before submitting"],"tags":["tmux","codex","submit-verification","race-condition"],"backgroundTag":"submit-verification-failed","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}