karatelabs/karate · error · RuntimeException

expect().to.have.nested - no such api:

Error message

expect().to.have.nested - no such api: 

What it means

Unknown-API sentinel in Expect's initExpectToHaveNested: the expect().to.have.nested accessor is a switch over API key names (e.g. a property path), and this fires when an unsupported property is accessed after expect(...).to.have.nested. The input at fault is the unrecognized key string appended to the message, indicating a typo or unsupported .have.nested sub-API.

Solutions

  1. Use expect(obj).to.have.nested.property('a.b.c') exactly
  2. Or use karate path matching: match obj.a.b == '#present' or json path assertions via match
  3. Confirm key spelling matches 'property'

Example fix

// before
expect(obj).to.have.nested.path('a.b') // no such api: path
// after
expect(obj).to.have.nested.property('a.b')
Defensive patterns

Strategy: validation

Validate before calling

if (key !== 'property') throw 'only .to.have.nested.property is supported, got: ' + key;

Try / catch

try { expect(obj).to.have.nested.property('a.b.c'); } catch (e) { karate.log(e.message); }

Prevention

When it happens

Trigger: expect(obj).to.have.nested.<key>(...) where key != 'property', e.g. .to.have.nested.path('a.b.c') or Chai's .to.have.nested.include(...).

Common situations: Chai's nested include plugin syntax copied into Karate; typos like propertie or prop.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at karate-core/src/main/java/io/karatelabs/match/Expect.java:389

                    try {
                        json = Json.of(subject);
                    } catch (Exception e) {
                        Result fail = Result.fail("expected to have property: " + path);
                        handleResult(context, fail);
                        return new Expect(subject, false, onResult, throwOnFailure, contextSupplier);
                    }
                    Result result;
                    if (args.length > 1) {
                        Object actual = json.get(path, null);
                        result = evaluate(actual, Match.Type.EQUALS, args[1]);
                    } else {
                        result = json.pathExists(path) ? Result.PASS : Result.fail("expected to have property: " + path);
                    }
                    handleResult(context, result);
                    return new Expect(subject, false, onResult, throwOnFailure, contextSupplier);
                };
            } else {
                throw new RuntimeException("expect().to.have.nested - no such api: " + key);
            }
        };
    }

    @SuppressWarnings("unchecked")
    private SimpleObject initExpectToHave() {
        return key -> switch (key) {
            case "not" -> new Expect(subject, !negated, onResult, throwOnFailure, contextSupplier).expectToHave;
            case "that", "and", "which" -> this;
            case "length" -> handleChainable(rhs -> {
                if (rhs instanceof Number n) {
                    String message = "actual: " + subject + ", expected: (length=" + n + ")";
                    if (subject instanceof String s) {
                        return s.length() == n.intValue() ? null : message;
                    } else if (subject instanceof Map) {
                        Map<String, Object> map = (Map<String, Object>) subject;
                        return n.equals(map.get("length")) ? null : message;
                    } else if (subject instanceof List<?> l) {

View on GitHub (pinned to a22eb90246)