karatelabs/karate · error · DriverException
no page found with targetId
Error message
no page found with targetId: ${targetId} What it means
CdpDriver.switchPageById(targetId) verifies, within its auto-wait budget, that a page target with the given targetId still exists before activating it; after exhausting fast-poll attempts it throws this DriverException. This guards against activating stale or already-closed targets.
Solutions
- Refresh the list of valid ids via getPages()/targets and pick an existing id before switching
- Re-capture the target id after any reload or driver restart instead of caching it
- Increase the fast-poll budget in config if the tab is opened just-in-time
- Verify the id refers to a page-type target (not iframe/worker) via devtools Target.getTargets
Example fix
// before String savedId = capturedTargetId; // from earlier scenario step driver.switchPageById(savedId); // after String freshId = driver.getPages().stream().filter(id -> pageMatches(id)).findFirst().orElse(null); driver.switchPageById(freshId);
Defensive patterns
Strategy: fallback
Validate before calling
String freshId = driver.getPages().stream()
.filter(id -> id.equals(savedId))
.findFirst().orElse(null);
if (freshId == null) { logger.warn("saved targetId no longer exists; re-resolving"); } Try / catch
try {
driver.switchPageById(savedId);
} catch (DriverException e) {
if (e.getMessage().contains("no page found with targetId")) {
driver.switchPage(expectedUrlSubstring); // fallback: re-resolve by URL
return;
}
throw e;
} Prevention
- Re-capture target ids after reloads or driver restarts; never cache across sessions
- Prefer switching by URL/title substring over long-lived target ids
- Check that the id is a page target, not an iframe/worker, before switching
When it happens
Trigger: switchPageById(id) where the tab with that id was closed, navigated in a way that replaced the target, the id is from a previous browser session, or Target.getTargets keeps omitting it (e.g. it is an iframe/worker target, not a page).
Common situations: Test closed the tab earlier in the same scenario; reusing target ids captured before a driver restart; hard refresh or SPA reload replaced the target id; id points at a non-page target type.
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 found matching
- no page at index
- 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/604dae7db0da5f1e.
Report an issue: GitHub.
Appendix: source
Thrown at karate-core/src/main/java/io/karatelabs/driver/cdp/CdpDriver.java:4003
logger.debug("switch page by targetId: {}", targetId);
if (targetId == null) {
throw new DriverException("targetId is null");
}
// Verify the target exists as a page target before activating, retrying within
// the auto-wait budget: Target.getTargets can briefly lag a freshly opened tab.
int interval = fastPollInterval();
int maxAttempts = fastPollAttempts();
for (int attempt = 0; ; attempt++) {
if (getPages().contains(targetId)) {
activateTarget(targetId);
return;
}
if (attempt >= maxAttempts) {
break;
}
sleep(interval);
}
throw new DriverException("no page found with targetId: " + targetId);
}
/**
* Drain the queue of page targets (tabs) opened since the last call.
* Event-driven — no CDP round-trip. See {@link Driver#drainOpenedTargets()}.
*/
@Override
public List<Map<String, Object>> drainOpenedTargets() {
if (openedTargets.isEmpty()) {
return java.util.Collections.emptyList();
}
List<Map<String, Object>> drained = new ArrayList<>();
Map<String, Object> entry;
while ((entry = openedTargets.poll()) != null) {
drained.add(entry);
}
return drained;
}View on GitHub (pinned to a22eb90246)