karatelabs/karate · error · DriverException
No tab found matching
Error message
No tab found matching: ${titleOrUrl} What it means
W3cDriver.tab(target) with a String target iterates all window handles, switching to each and testing whether its title or URL contains the given text. If no tab matches, it restores the original handle and throws DriverException 'No tab found matching: <titleOrUrl>'. Matching is substring-based and case/whitespace-sensitive.
Solutions
- Print the open tabs' titles/URLs (windowHandles + getTitle/getUrl per handle) and match a substring that actually appears
- Match on a stable URL fragment instead of a volatile title
- Wait for the target tab to finish loading before searching
- Trim/normalize the search string and account for URL encoding
Example fix
// before
tab('My Account Dashboard'); // h1 text, not the tab title
// after
tab('/account/dashboard'); // stable URL substring Defensive patterns
Strategy: validation
Validate before calling
// confirm a matching tab exists before switching
boolean found = driver.windowHandles().stream().anyMatch(h ->
driver.getTitle(h).contains(expected) || driver.getUrl(h).contains(expected));
if (!found) throw new AssertionError("no tab matching " + expected); Try / catch
try {
driver.tab(titleOrUrl);
} catch (DriverException e) {
if (e.getMessage().startsWith("No tab found matching")) {
// dump handles/titles for diagnosis, then use index fallback
} else throw e;
} Prevention
- Match on stable URL fragments, not display headings
- Remember matching is substring- and case-sensitive
- Wait for the target tab to load before searching
- Normalize/trim search strings and account for URL encoding
When it happens
Trigger: Calling tab('Some Title') or tab('/some/path') when no open tab's title or URL contains that exact substring — wrong casing, partial/split text, URL-encoded characters, or the target tab never opened.
Common situations: Page title differs from the visible heading (browser tab title vs h1); URL fragments or query params encoded (e.g. %20 vs space); popup opened in a new window the driver doesn't track; title changed dynamically after load; trailing whitespace in the search string.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- Tab index out of bounds
- Could not find active element for keyboard input
- Dialog callback handler not supported on WebDriver backend…
- Element not found
- Error closing driver
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/e49a86c5aca78bda.
Report an issue: GitHub.
Appendix: source
Thrown at karate-core/src/main/java/io/karatelabs/driver/w3c/W3cDriver.java:358
throw new DriverException("Tab index out of bounds: " + index
+ " (available: " + handles.size() + ")");
}
} else if (target instanceof String) {
String titleOrUrl = (String) target;
String currentHandle = session.getWindowHandle();
List<String> handles = session.getWindowHandles();
for (String handle : handles) {
session.switchWindow(handle);
String title = session.getTitle();
String url = session.getUrl();
if ((title != null && title.contains(titleOrUrl))
|| (url != null && url.contains(titleOrUrl))) {
return; // Found it
}
}
// Not found, restore original
session.switchWindow(currentHandle);
throw new DriverException("No tab found matching: " + titleOrUrl);
}
}
// ========== Element Operations ==========
//
// V1 PATTERN: Almost all element operations use JS eval, NOT native W3C element endpoints.
// This was a deliberate, battle-tested choice in v1:
// - click() uses JS .click() — more reliable across browsers than POST /element/{id}/click
// - text/html/value/attribute/enabled all use JS — avoids stale element reference issues
// - clear() uses JS value = '' — more consistent than POST /element/{id}/clear
// - ONLY input() uses native W3C sendKeys — because JS can't simulate real keyboard events
// that trigger framework event handlers (React, Vue, Angular)
//
// The single-retry pattern in eval() provides the retry safety net for all JS operations.
@Override
public Element click(String locator) {
// v1 pattern: JS click, not W3C endpoint — more reliable, handles shadow DOM, custom elementsView on GitHub (pinned to a22eb90246)