karatelabs/karate · error · RuntimeException

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

Error message

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

What it means

Unknown-API guard in initExpectToHave: the property chained after expect().to.have is not one of the supported assertion APIs (property access, keys, etc.). Fires on misspelled DSL keys; the message appends the invalid key.

Solutions

  1. Use supported keys: expect(x).to.have.property('name') / .to.have.keys(...) / .all / .any / .nested.property(...)
  2. For length/size use expect(list.size() == 3) or match each/list syntax
  3. Consult the expect() API docs for the exact key list

Example fix

// before
expect(list).to.have.length(3) // no such api: length
// after
expect(list.size() == 3)
Defensive patterns

Strategy: validation

Validate before calling

var haveKeys = ['property','properties','keys','all','any','nested'];
if (haveKeys.indexOf(key) < 0) throw 'unsupported .to.have key: ' + key;

Try / catch

try { expect(obj).to.have.property('name'); } catch (e) { karate.log(e.message); }

Prevention

When it happens

Trigger: expect(obj).to.have.<key>(...) with an unsupported key such as .to.have.length(n) (use .to.have.size? — only supported keys work), .to.have.string, or typos like propreties.

Common situations: Chai idioms like .to.have.lengthOf, .to.have.property misspelled; assuming all Chai vocabulary exists in Karate.

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/6a1cf79b49465460. Report an issue: GitHub.

Appendix: source

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

                }
                handleResult(context, result);
                // Return chainable with property value as new subject for .and.equal() chaining
                return new Expect(propertyValue != null ? propertyValue : subject, false, onResult, throwOnFailure, contextSupplier);
            };
            case "keys" -> (JavaCallable) (context, args) -> {
                Result result;
                if (subject instanceof Map<?, ?> map) {
                    result = evaluate(map.keySet(), Match.Type.CONTAINS_ONLY, args[0]);
                } else {
                    result = Result.fail("not an object");
                }
                handleResult(context, result);
                return new Expect(subject, false, onResult, throwOnFailure, contextSupplier);
            };
            case "all" -> expectToHaveAll;
            case "any" -> expectToHaveAny;
            case "nested" -> expectToHaveNested;
            default -> throw new RuntimeException("expect().to.have - no such api: " + key);
        };
    }

    private SimpleObject initExpectTo() {
        return key -> switch (key) {
            case "that", "and", "which" -> this;
            case "equal", "eql" -> match(Match.Type.EQUALS);
            case "include", "contain" -> matchChainable(Match.Type.CONTAINS);
            case "deep" -> expectToDeep;
            case "be" -> expectToBe;
            case "exist" -> {
                Result result = (subject != null && subject != Terms.UNDEFINED) ? Result.PASS : Result.fail("actual: " + subject + ", expected: (exists)");
                handleResult(null, result);
                yield new Expect(subject, false, onResult, throwOnFailure, contextSupplier);
            }
            case "have" -> expectToHave;
            case "match" -> (JavaCallable) (context, args) -> {
                Result result;

View on GitHub (pinned to a22eb90246)