karatelabs/karate · error · DriverException
no page found matching
Error message
no page found matching: ${titleOrUrl} What it means
A page-switch helper (switchPage-style polling over CDP targets) exhausts its retry attempts without finding a page target whose title or URL contains the given substring, then throws this DriverException. Karate retries at a fast poll interval so freshly opened tabs are picked up, but if no matching target appears the wait is abandoned.
Solutions
- List current targets (getPages / Target.getTargets via devtools) and match the argument against actual titles/URLs
- Increase the switch timeout/retry config so slow popups are covered
- Ensure the action that opens the new tab actually executed (check for popup blockers)
- Pass a stable substring of the final URL (after redirects) rather than the initial about:blank or transient title
Example fix
// before
driver.switchPage("Reports Dashboard");
// after
logger.debug("pages={}", driver.getPages());
String url = (String) driver.script("window.location.href");
driver.switchPage(url.contains("reports") ? "reports" : "Reports Dashboard"); Defensive patterns
Strategy: retry
Validate before calling
List<String> pages = driver.getPages();
if (pages.isEmpty()) { throw new IllegalStateException("no page targets open"); } Try / catch
try {
driver.switchPage("Reports Dashboard");
} catch (DriverException e) {
logger.error("no matching tab; open targets={}", driver.getPages());
// one retry in case the popup was slow
karate.call.sleep(1000);
driver.switchPage("Reports");
} Prevention
- Switch by a stable substring of the final URL, not transient titles
- Confirm the popup-opening action succeeded (popup blockers!) before switching
- Inspect getPages()/targets when a match fails instead of guessing strings
When it happens
Trigger: switchPage(titleOrUrl) (or the matching driver keyword) called with a substring that matches no open tab's title or URL — the tab never opened, closed before the switch, or the title/URL differs from the argument.
Common situations: window.open / target=_blank link never fired (popup blocked); new tab URL is an exact match only but the argument is a partial string from an older app version; tab closed by the app before the poll; typos or case-sensitivity in the substring.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- no page at index
- no page found with targetId
- targetId is null
- bad wildcard locator
- configure driver = } — bypassing driver pool; browser will…
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/3690636ca99ab8c8.
Report an issue: GitHub.
Appendix: source
Thrown at karate-core/src/main/java/io/karatelabs/driver/cdp/CdpDriver.java:3961
// Retry the enumeration: Target.getTargets can transiently lag a freshly
// opened/closed tab, or report a page whose url/title field is not yet
// populated while it is still loading - especially under parallel load. A
// single-shot lookup then spuriously throws "no page found" (observed flaky
// on tab-switch under CI). Poll within the same budget as other auto-waits.
int interval = fastPollInterval();
int maxAttempts = fastPollAttempts();
for (int attempt = 0; ; attempt++) {
String targetId = findPageTarget(titleOrUrl);
if (targetId != null) {
activateTarget(targetId);
return;
}
if (attempt >= maxAttempts) {
break;
}
sleep(interval);
}
throw new DriverException("no page found matching: " + titleOrUrl);
}
/**
* Find a page target whose title or URL contains the given substring, or null.
*/
private String findPageTarget(String titleOrUrl) {
for (Map<String, Object> target : pageTargets()) {
String title = (String) target.get("title");
String url = (String) target.get("url");
if ((title != null && title.contains(titleOrUrl)) ||
(url != null && url.contains(titleOrUrl))) {
return (String) target.get("targetId");
}
}
return null;
}
/**View on GitHub (pinned to a22eb90246)