karatelabs/karate · error · AssertionError

expected status: , actual:

Error message

expected status: , actual: 

What it means

The `status <code>` step asserts that the last HTTP response's status equals the expected integer. When the actual `responseStatus` variable differs, StepExecutor throws an AssertionError showing both values, failing the scenario's HTTP assertion.

Solutions

  1. Compare expected vs actual in the message; if the actual is correct, update the step (e.g. `status 201`).
  2. Inspect `response` in the report to understand why the server returned that status.
  3. Fix auth, URL, or payload issues causing the non-success status.
  4. Use `status [200, 204]`-style matching or soft assertions if multiple statuses are acceptable.

Example fix

// before
And status 200
// after (endpoint legitimately returns 201 on create)
And status 201
Defensive patterns

Strategy: validation

Validate before calling

// Assert status manually first to get a richer failure message
And def actualStatus = responseStatus
* if (actualStatus != 200) karate.log('unexpected status ' + actualStatus + ' body: ' + response)
And status 200

Prevention

When it happens

Trigger: A `status 200` (or similar) step ran after an HTTP call whose actual response status differed, e.g. server returned 404, 500, 401.

Common situations: Endpoint changed or route misspelled (404); authentication missing/expired (401); server-side bug (500); asserting 200 when an API intentionally returns 201/204; environment pointing at the wrong service.

Related errors


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

Appendix: source

Thrown at karate-core/src/main/java/io/karatelabs/core/StepExecutor.java:2407

                }
                return response;
            } else {
                logger.debug("retry condition not satisfied: {}", retryUntil);
            }

            // Restore request state for next retry (http().invoke() resets it)
            http().restoreFrom(httpCopy);

            retryCount++;
        }
    }

    private void executeStatus(Step step) {
        int expected = Integer.parseInt(step.getText().trim());
        Object statusObj = runtime.getVariable("responseStatus");
        int actual = statusObj instanceof Number n ? n.intValue() : Integer.parseInt(statusObj.toString());
        if (actual != expected) {
            throw new AssertionError("expected status: " + expected + ", actual: " + actual);
        }
    }

    /**
     * Handles: multipart file myFile = { read: 'file.txt', filename: 'test.txt', contentType: 'text/plain' }
     * Or shorthand: multipart file myFile = read('file.txt')
     */
    @SuppressWarnings("unchecked")
    private void executeMultipartFile(Step step) {
        String text = step.getText();
        int eqIndex = StepUtils.findAssignmentOperator(text);
        if (eqIndex < 0) {
            throw new RuntimeException("multipart file requires '=' assignment: " + text);
        }
        String name = text.substring(0, eqIndex).trim();
        String expr = text.substring(eqIndex + 1).trim();

        Object value = evalKarateExpression(expr);

View on GitHub (pinned to a22eb90246)