jackwener/OpenCLI · error · CommandExecutionError

Failed to send message

Error message

Failed to send message

What it means

sendMessage() failed to submit the prompt into the composer (sendResult not ok). The library raises CommandExecutionError with the specific reason when available, else the generic 'Failed to send message'.

Source

Thrown at clis/claude/ask.js:133

                // SPA navigates after send; "Promise was collected" means send succeeded
                if (!String(err?.message || err).includes('Promise was collected')) throw err;
            }
            // Pre-waitForResponse settle dropped — waitForResponse's first 3 s polling
            // tick covers the same window without an unconditional sleep.
            const result = await waitForResponse(page, baseline, prompt, timeoutMs);
            if (!result) {
                throw new EmptyResultError(
                    'claude ask',
                    `No Claude response appeared within ${timeoutSeconds}s. Re-run with a higher --timeout if the model is still generating.`,
                );
            }
            return [{ response: result }];
        }

        const baseline = await withRetry(() => getBubbleCount(page));
        const sendResult = await withRetry(() => sendMessage(page, prompt));
        if (!sendResult?.ok) {
            throw new CommandExecutionError(sendResult?.reason || 'Failed to send message');
        }

        const result = await waitForResponse(page, baseline, prompt, timeoutMs);
        if (!result) {
            throw new EmptyResultError(
                'claude ask',
                `No Claude response appeared within ${timeoutSeconds}s. Re-run with a higher --timeout if the model is still generating.`,
            );
        }
        return [{ response: result }];
    },
});

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Re-run the command; withRetry may succeed on a fresh attempt.
  2. Verify the claude.ai session is valid and the composer renders (re-authenticate if needed).
  3. Check for Claude-side banners (rate limits, out of credits) blocking submission.
  4. Update opencli if Claude's composer markup changed.
Defensive patterns

Strategy: retry

Validate before calling

// Ensure a live session before sending
await opencli.claude.whoami(); // throws AuthRequiredError early if session is dead

Try / catch

try {
  return await opencli.claude.ask(prompt);
} catch (e) {
  if (/Failed to send message/.test(e.message)) {
    await sleep(5000);
    return await opencli.claude.ask(prompt, { new: true });
  }
  throw e;
}

Prevention

When it happens

Trigger: `claude ask "..."` without --file where withRetry(sendMessage) returns {ok:false} — composer not found or disabled, send button unreachable, network hiccup, or send rejected by the page.

Common situations: Claude web session logged out mid-run; rate-limit/credit-exhausted banner blocking the composer; UI change breaking the send selector; composer never mounted after navigation.

Related errors


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