jackwener/OpenCLI · error · CommandExecutionError

Gemini generation probe failed

Error message

Gemini generation probe failed

What it means

Thrown by isGeminiGenerating when page.evaluate of the isGeneratingExpression script itself throws (navigation, detached execution context, script syntax/runtime error). The original browser error message is preserved as the second argument of CommandExecutionError, and the wrapper normalizes it for callers of the generation probe.

Source

Thrown at clis/gemini/utils.js:2379

      }
      return urls;
    })()
  `);
    const urls = requireGeminiArrayResult(result, 'Gemini image detection');
    if (!urls.every((url) => typeof url === 'string')) {
        throw new CommandExecutionError('Gemini image detection returned a malformed result');
    }
    return urls;
}
/** Cheap generation probe: the snapshot read walks the whole transcript. */
export async function isGeminiGenerating(page) {
    let result;
    try {
        result = await page.evaluate(`(() => ${isGeneratingExpression()})()`);
    }
    catch (error) {
        const message = error instanceof Error ? error.message : String(error);
        throw new CommandExecutionError('Gemini generation probe failed', message);
    }
    const value = unwrapGeminiEvaluateResult(result, 'Gemini generation probe');
    if (typeof value !== 'boolean') {
        throw new CommandExecutionError('Gemini generation probe returned a malformed result');
    }
    return value;
}
export async function waitForGeminiImages(page, beforeUrls, timeoutSeconds) {
    const beforeSet = new Set(beforeUrls);
    const pollIntervalSeconds = 3;
    const maxPolls = Math.max(1, Math.ceil(timeoutSeconds / pollIntervalSeconds));
    let lastUrls = [];
    let stableCount = 0;
    let stillGenerating = false;
    for (let index = 0; index < maxPolls; index += 1) {
        await page.wait(index === 0 ? 2 : pollIntervalSeconds);
        // The text waits already gate on this signal; without it the image wait
        // can settle on whatever is on screen mid-generation (#2245). An

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Retry the probe — navigation-timing races are transient and a re-poll usually succeeds.
  2. Read the wrapped cause (second arg / error.cause) to identify the underlying evaluate failure.
  3. Ensure the page isn't navigating during polling; wait for URL stability before probing.
  4. Add null/DOM guards inside isGeneratingExpression so missing nodes return false instead of throwing.
  5. Re-create the page/browser if the execution context is permanently gone (tab closed).
Defensive patterns

Strategy: try-catch

Try / catch

let generating = false;
try {
  generating = await isGeminiGenerating(page);
} catch (e) {
  const cause = e.cause || e.message;
  if (String(cause).includes('probe failed')) { await page.wait(1); generating = await isGeminiGenerating(page); }
  else throw e;
}

Prevention

When it happens

Trigger: Polling isGeminiGenerating while the page navigates to a new conversation URL (execution context destroyed), the tab crashed/closed, or the in-page expression throws at runtime because expected DOM nodes are absent and the expression doesn't guard them.

Common situations: Race between submission and Gemini's client-side navigation; slow/unstable network causing context loss; headless browser killed mid-poll; Gemini deploying an update mid-session that breaks the probe expression.

Related errors


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