jackwener/OpenCLI · error · CommandExecutionError
${send?.reason || 'Failed to send Grok prompt'}
Error message
${send?.reason || 'Failed to send Grok prompt'} What it means
After sendPrompt runs, the command checks its result; on failure it first re-verifies login (throwing AuthRequiredError if logged out) and otherwise throws CommandExecutionError carrying send.reason or the default 'Failed to send Grok prompt'. This means the composer was present and the session valid, but submission still failed for another reason.
Source
Thrown at clis/grok/send.js:46
func: async (page, kwargs) => {
const prompt = String(kwargs.prompt || '').trim();
if (!prompt) throw new ArgumentError('prompt', 'is required');
const startFresh = normalizeBooleanFlag(kwargs.new, false);
await ensureOnGrok(page);
if (startFresh) {
await startNewChat(page);
}
const send = await sendMessage(page, prompt);
if (!send?.ok) {
// If the composer is missing, the most likely cause is that the
// signed-in session expired (Grok then renders a sign-in CTA in
// place of the composer). Surface that as AuthRequiredError so
// agents can prompt for re-auth instead of treating it as a
// generic execution failure.
if (!(await isLoggedIn(page))) throw authRequired();
throw new CommandExecutionError(send?.reason || 'Failed to send Grok prompt');
}
return [{ Status: 'sent', Prompt: prompt }];
},
});
View on GitHub (pinned to 49907e53dc)
Solutions
- Read send.reason in the message for the specific failing step.
- Retry after a short wait — rate limits and transient click failures often clear.
- Reload the tab, dismiss any dialogs, confirm the composer accepts manual input.
- Check for Grok usage limits on the account; update the library if the UI changed.
Example fix
// before
cli send 'hello' // {ok:false, reason:'send click did not submit'}
// after
// dismiss the quota dialog in the tab / wait out the rate limit, then
cli send 'hello' Defensive patterns
Strategy: try-catch
Validate before calling
// Confirm session and composer before sending:
const composer = await page.waitForSelector('textarea', { timeout: 5000 }).catch(() => null);
if (!composer) throw new Error('composer missing — session may need re-auth'); Try / catch
try {
await cli.send({ prompt });
} catch (e) {
if (e instanceof AuthRequiredError) {
console.error('Re-authenticate grok.com in the automated tab.');
} else if (e instanceof CommandExecutionError && /Failed to send Grok prompt/.test(e.message)) {
console.warn('Send failed while logged in; retrying after backoff...');
await new Promise(r => setTimeout(r, 5000));
return cli.send({ prompt });
} else throw e;
} Prevention
- Distinguish AuthRequiredError from generic send failures and handle each differently.
- Watch for Grok rate limits and back off between sends.
- Dismiss dialogs that can intercept the send action.
- Log send.reason to identify the exact failing step.
When it happens
Trigger: sendPrompt returns {ok:false} with a reason while isLoggedIn(page) is true — e.g. the send click didn't register, the composer rejected input, or submission was blocked by a rate limit/dialog.
Common situations: Grok rate limiting prompts, an unexpected modal (quota upsell, safety notice) intercepting submission, partial session validity, or DOM changes breaking send mechanics without logging the user out.
Related errors
- STATE_VERIFY_FAIL: follow button did not flip to Following w
- Unexpected 12306 probe: ${JSON.stringify(probe)}
- Waiting for 12306 tk auth cookie
- API_ERROR
- API_ERROR
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/b8738675c94bb9dd.
Report an issue: GitHub.