jackwener/OpenCLI · error · CommandExecutionError

Codex send was not verified.

Error message

Codex send was not verified.

What it means

After the second Enter (submitting the draft/command), the library polls the composer state; a successful send empties the composer. If `state.text` is still non-empty, the draft was not sent and this error is thrown, distinguishing a silent failed submit from a false success.

Source

Thrown at clis/codex/send.js:231

            // still-loaded composer is either the untouched draft or the chip
            // the picker resolved. Anything else was rewritten: never submit.
            const slashToken = /^\/\S+$/.test(textToInsert) ? textToInsert.slice(1) : '';
            const chipLabel = picked ? picked.title : slashToken;
            const unchangedDraft = state.chips.length === 0 && state.text === String(textToInsert).trim();
            const pickerResolvedCommand = chipLabel !== ''
                && state.chips.length === 1
                && state.nonChipText === ''
                && chipMatchesLabel(state.chips[0], chipLabel);
            if (!unchangedDraft && !pickerResolvedCommand) {
                throw new CommandExecutionError(
                    'Codex send was not submitted.',
                    `The composer now holds ${describeComposerState(state)}. Re-run with --pick <label> or press Escape in Codex first.`,
                );
            }
            await page.pressKey('Enter');
            state = await pollComposerState(page);
            if (state.text) {
                throw new CommandExecutionError('Codex send was not verified.', `The composer still holds an unsent draft: ${describeComposerState(state)}`);
            }
        }
        return [
            {
                Status: 'Success',
                Project: selected?.project || '',
                Conversation: selected?.conversation || '',
                InjectedText: textToInsert,
            },
        ];
    },
});

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Re-run the send after confirming the Codex window is focused and idle.
  2. Dismiss any modal/dialog blocking the composer, then retry.
  3. Check Codex connectivity/backend health if the draft consistently fails to send.
  4. Clear the composer (Escape) and retry to rule out a stuck draft state.
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await codexSend({ text });
} catch (e) {
  if (String(e.message).includes('send was not verified')) {
    // ensure window focus, dismiss modals, then retry
    await bringToFront(page);
    await codexSend({ text });
  } else throw e;
}

Prevention

When it happens

Trigger: `pollComposerState` still reports text in the composer after Enter — Enter was swallowed (focus not on composer), Codex rejected the send (e.g. backend busy), a modal intercepted the keypress, or the composer retained residual text.

Common situations: Codex lost composer focus after a picker interaction; network/backend issue prevented submission; a Codex dialog (e.g. confirm/upgrade prompt) stole the Enter key; very long draft triggered client-side throttling.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/ee628be30cfaa256. Report an issue: GitHub.