jackwener/OpenCLI · error · CommandExecutionError
Codex send was not submitted.
Error message
Codex send was not submitted.
What it means
After pressing Enter the first time, the library re-reads the composer state. A submitted command must either leave the draft unchanged (`unchangedDraft`: no chips and original text intact, meaning Enter opened the picker instead) or resolve to exactly one chip with no other text (`pickerResolvedCommand`). Anything else means the composer was mutated unexpectedly and the send cannot proceed safely.
Source
Thrown at clis/codex/send.js:223
`expected=${picked.title} ${describeComposerState(applied ?? { text: '', chips: [] })}`,
);
}
}
await page.pressKey('Enter');
let state = await pollComposerState(page);
if (state.text) {
// The picker consumes Enter to insert the highlighted entry, so a
// 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
- Press Escape in Codex to clear the composer, then re-run the command.
- Re-run with `--pick <label>` so the command goes through the picker flow explicitly.
- Manually clear the composer of leftover chips/text before retrying.
- Ensure no concurrent typing/automation is interacting with the Codex composer.
Example fix
// before (dirty composer)
await codexSend(page, '/review'); // composer had leftover text
// after
codexSend(page, '/review', { preflight: async (p) => { await p.pressKey('Escape'); } }); Defensive patterns
Strategy: validation
Validate before calling
// Check composer is clean before sending
const state = await readComposerState(page);
if (state.chips.length > 0 || state.text.trim() !== '') {
throw new Error('Composer not clean; press Escape in Codex first');
} Type guard
const isCleanComposer = (s) => s && s.chips.length === 0 && typeof s.text === 'string' && s.text.trim() === '';
Try / catch
try {
await codexSend({ text });
} catch (e) {
if (String(e.message).includes('send was not submitted')) {
await page.pressKey('Escape'); // clear composer, then retry
} else throw e;
} Prevention
- Always start from an empty composer (Escape first).
- Never interleave manual typing with automated sends.
- Use `--pick <label>` for slash commands instead of typing raw text.
- Check the error's composer-state detail to see what was left behind.
When it happens
Trigger: Composer state after Enter matches neither `unchangedDraft` nor `pickerResolvedCommand` — e.g. partial text remains alongside a chip, multiple chips exist, or the draft text was altered by Codex (autocorrect, formatting, pre-filled content).
Common situations: Composer already contained leftover text/chips from a previous failed attempt; Codex converted the slash command into something other than a single chip; user (or another automation) typed into the composer mid-send.
Related errors
- Codex picker selection did not reach the composer.
- Codex send was not verified.
- Failed to send message
- Codex picker option disappeared before it could be clicked.
- Could not find Antigravity input box
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/677c7efe311049cc.
Report an issue: GitHub.