karatelabs/karate · error · DriverException

WebDriver session create response missing sessionId: " +…

Error message

WebDriver session create response missing sessionId: " + response.body()

What it means

After a 200 response, W3cSession.create parses the JSON body and throws DriverException if the `value.sessionId` field is absent, including the raw body in the message. A 200 without a sessionId is a malformed/unexpected response from whatever answered the WebDriver port.

Solutions

  1. Verify the host/port points at the real WebDriver endpoint (curl /status and inspect the response)
  2. Inspect the echoed body in the message to see what actually replied
  3. Use a W3C-compliant driver version (legacy JSON-wire drivers put sessionId outside value)
  4. Bypass proxies for localhost so the request reaches the driver directly

Example fix

// before
driver('type', 'chromedriver', 'port', 9222); // 9222 is DevTools, not chromedriver
// after
driver('type', 'chromedriver', 'port', 9515); // default chromedriver port
Defensive patterns

Strategy: validation

Validate before calling

// confirm the endpoint really is WebDriver before session create
// GET /status must return 200 with { value: { ready: true, ... } }

Type guard

boolean isW3cSessionBody(Map<String, Object> body) {
    return body.get("value") instanceof Map<?,?> v && v.get("sessionId") instanceof String;
}

Try / catch

try {
    session = W3cSession.create(client, baseUrl, caps, timeout);
} catch (DriverException e) {
    if (e.getMessage().contains("missing sessionId")) {
        // inspect echoed body; fix host/port or driver protocol version
    }
}

Prevention

When it happens

Trigger: POST /session returns HTTP 200 but the body lacks value.sessionId — e.g. an intermediate proxy answered, the endpoint is not actually a WebDriver server, or a non-W3C (legacy JSON wire) driver returned a different body shape.

Common situations: Pointing the driver at the wrong port (another HTTP service listening there); corporate proxy intercepting the request; using an old driver that returns sessionId at the top level (pre-W3C protocol).

Understand the failure class

Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.

Related errors


AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12). Data as JSON: /api/errors/a5ae82b25622b45a. Report an issue: GitHub.

Appendix: source

Thrown at karate-core/src/main/java/io/karatelabs/driver/w3c/W3cSession.java:120

            requestBuilder.header("Authorization", basicAuth);
        }

        HttpRequest request = requestBuilder
                .POST(HttpRequest.BodyPublishers.ofString(json))
                .build();

        try {
            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
            if (response.statusCode() != 200) {
                throw new DriverException("WebDriver session create failed with status "
                        + response.statusCode() + ": " + response.body());
            }

            Map<String, Object> body = Json.of(response.body()).asMap();
            Map<String, Object> value = (Map<String, Object>) body.get("value");
            String sessionId = (String) value.get("sessionId");
            if (sessionId == null) {
                throw new DriverException("WebDriver session create response missing sessionId: " + response.body());
            }

            logger.info("W3C session created: {}", sessionId);
            return new W3cSession(client, baseUrl, sessionId, timeout);
        } catch (IOException | InterruptedException e) {
            if (e instanceof InterruptedException) {
                Thread.currentThread().interrupt();
            }
            throw new DriverException("WebDriver session create failed: " + e.getMessage(), e);
        }
    }

    // ========== Navigation ==========

    public void navigateTo(String url) {
        post("url", Map.of("url", url));
    }

View on GitHub (pinned to a22eb90246)