jackwener/OpenCLI · error · EmptyResultError
No Claude response appeared within ${timeoutSeconds}s. Re-ru
Error message
No Claude response appeared within ${timeoutSeconds}s. Re-run with a higher --timeout if the model is still generating. What it means
After a file-backed send, waitForResponse() polled for a new Claude message bubble beyond the pre-send baseline and returned null at the timeout. The library throws EmptyResultError telling the user to raise --timeout if the model is still generating.
Source
Thrown at clis/claude/ask.js:122
// Post-toggle settle dropped — the next CDP eval (sendMessage / sendWithFile)
// gives React enough time to flush aria-checked updates.
if (kwargs.file) {
const baseline = await withRetry(() => getBubbleCount(page));
try {
const fileResult = await sendWithFile(page, kwargs.file, prompt);
if (fileResult && !fileResult.ok) {
throw new CommandExecutionError(fileResult.reason || 'Failed to attach file');
}
} catch (err) {
// 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.`,View on GitHub (pinned to 49907e53dc)
Solutions
- Re-run with a higher --timeout (e.g. --timeout 300).
- Check the Claude tab manually to confirm the message actually sent.
- Reduce the prompt/file size to shorten generation time.
Example fix
// before opencli claude ask "analyze this" --file big.pdf --timeout 30 // after opencli claude ask "analyze this" --file big.pdf --timeout 300
Defensive patterns
Strategy: retry
Validate before calling
// Size the timeout to the workload: file analysis needs more time
const timeout = opts.file ? 300 : 120;
if (opts.timeout && opts.timeout < (opts.file ? 180 : 60)) {
console.warn('timeout is low; consider raising --timeout');
} Try / catch
try {
return await opencli.claude.ask(prompt, { file, timeout: 120 });
} catch (e) {
if (/No Claude response appeared within/.test(e.message)) {
return await opencli.claude.ask(prompt, { file, timeout: 600 });
}
throw e;
} Prevention
- Use generous --timeout for file-heavy prompts.
- Confirm the upload actually sent before waiting on the response.
- Escalate timeout on retries rather than repeating the same value.
When it happens
Trigger: `claude ask ... --file x` where no response appears within timeoutSeconds (default 120) — slow model generation, upload stuck, or the bubble-count never increased.
Common situations: Long generation on complex prompts with attached PDFs/images; very low --timeout value; upload failed silently so the message never sent.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Unexpected 12306 probe: ${JSON.stringify(probe)}
- antigravity copy-message
- ChatGPT did not create a conversation URL after sending the
- chatgpt image
- Failed to export generated ChatGPT image assets
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/53edbaccefd41774.
Report an issue: GitHub.