Troubleshooting & FAQ

Solutions to common Donobu errors including PageAiException, stale cache issues, AI provider errors, hanging tests, and self-healing problems.

PageAiException — flow stopped in a non-success state

Symptom: page.ai() throws with a message like page.ai flow stopped in state FAILED (expected SUCCESS).

Cause: The autonomous flow could not complete the instruction. This can happen when:

  • The instruction is ambiguous or refers to something not present on the page
  • The AI exhausted maxToolCalls without completing the goal
  • The page entered an unexpected state (e.g. an error dialog appeared)
  • The AI determined the objective is not achievable (NOT_COMPLETABLE state)

Fixes:

  • Rewrite the instruction to be more specific or goal-oriented
  • Increase maxToolCalls if the flow is genuinely complex:
    await page.ai('Complete the multi-step checkout process', {
      maxToolCalls: 50,
    });
    
  • Check for unexpected dialogs — see the Dialog handling section below
  • Use cache: false on the specific call, or set DONOBU_PAGE_AI_CLEAR_CACHE=1 / pass --clear-ai-cache, to force a fresh autonomous run and see whether the issue is a stale cache or a real failure

Inspecting the exception: You can catch PageAiException to log or respond to the specific failure state:

import { PageAiException } from 'donobu';

try {
  await page.ai('Complete the checkout');
} catch (e) {
  if (e instanceof PageAiException) {
    console.log('State:', e.metadata.state);
    console.log('Instruction:', e.originalInstruction);
  }
}

Stale cache producing wrong actions

Symptom: Tests fail with errors like "element not found" or "click target not visible" even though the page looks correct.

Cause: The cache was written against an older version of the page. The cached selectors no longer match the current DOM.

Fixes:

  1. Delete the relevant cache file: rm tests/.cache-lock/my-test.test.ts.cache.js
  2. Or pass --clear-ai-cache to npx donobu test, or set DONOBU_PAGE_AI_CLEAR_CACHE=1 before running, to invalidate all caches for the run and let the AI regenerate them
  3. Enable self-healing to have this happen automatically — see Self-Healing Tests

To identify whether a failure is cache-related, check the runMode field in test-flow-metadata.json attached to the test report. If it says DETERMINISTIC, the test was running from cache. Switch to cache: false to force an autonomous re-run.


AI provider errors

Symptom: GptApiKeysNotSetupException or similar error stating no AI connection is available.

Fix: Set at least one provider API key. The error message lists the accepted environment variables:

No AI connection available. Establish a connection by setting an API key via an environment variable.
Valid options:
  - ANTHROPIC_API_KEY
  - GOOGLE_GENERATIVE_AI_API_KEY
  - OPENAI_API_KEY

See AI Provider Configuration.

Symptom: 401 Unauthorized or quota-exceeded errors from the provider.

Fix: Verify the key is valid and has not expired. Check your quota/rate limits in the provider's dashboard. If you are using a Donobu key, check your credit balance on the Keys page.


Test appears to hang

Symptom: A test runs for a very long time and eventually times out, with no visible progress.

Common cause: The page displayed a native browser dialog (alert, confirm, or prompt) that Donobu's AI cannot interact with, because it is blocking JavaScript execution. The AI waits indefinitely for the dialog to be dismissed.

Fix: Ensure handleBrowserDialog is in the tool set (it is included by default). If you customised allowedTools and omitted it, add it back:

await page.ai('Proceed to the next step', {
  allowedTools: ['click', 'inputText', 'handleBrowserDialog'],
});

Alternatively, intercept the dialog at the Playwright level before calling page.ai:

page.on('dialog', (dialog) => dialog.accept());
await page.ai('Proceed to the next step');

Selector failover is not activating

Symptom: page.find(selector, { failover: [...] }) throws even though you expect a failover to match.

Cause: page.find builds a SmartSelector synchronously. Failover evaluation happens at action time (e.g. when .click() is called). If the error occurs before the action is awaited, the issue may be unrelated to failover.

Debugging:

  1. Confirm the primary selector is the one failing, not a downstream step
  2. Check that the failover selectors are correct by testing them individually with page.locator(failover[0]).isVisible()
  3. Ensure you are await-ing the action on the SmartSelector

Self-healing is not triggering

Symptom: Tests fail and are not self-healed.

Checks:

  1. Confirm you are running with npx donobu test --auto-heal
  2. Confirm an AI provider is configured — self-healing calls the AI and requires a working API key

Debugging tips

  • Verbose logging: Set DEBUG=donobu:* to enable detailed logs
  • Inspect the cache: Open .cache-lock/<test-file>.cache.js to see the exact tool calls that were cached; compare against what you expect the flow to do
  • Read test-flow-metadata.json: Every test attaches this file to the Playwright HTML report. It contains the final flow state, run mode, token counts, and the instructions passed to the AI
  • Open Donobu Studio: If you're running the tests locally, the full step-by-step timeline with screenshots is available in Studio. This is usually the fastest way to diagnose complex failures. See Viewing Test Results in Donobu Studio for more information.