karatelabs/karate · warning

jsKeys() not implemented for

Error message

jsKeys() not implemented for: {}

What it means

SimpleObject.toMap() is implemented via jsKeys(), but the default jsKeys() only logs this warning and returns an empty list. Converting such an object to a Map yields an empty map, so data silently disappears when objects are printed, matched, or passed around.

Solutions

  1. If you own the Java class, implement jsKeys() to return the actual key collection (and ensure getMember works for them)
  2. Convert the object explicitly to a Map in Java before exposing it to karate
  3. Note that the empty result is silent data loss — check for this warning whenever an object serializes to {}

Example fix

// before
class MyClass implements SimpleObject { } // jsKeys() default -> empty
// after
@Override public Collection<String> jsKeys() { return fields.keySet(); }
Defensive patterns

Strategy: validation

Type guard

// verify object converts non-empty before matching
var asMap = karate.toJson(obj); if (Object.keys(asMap).length === 0) karate.warn('object serialized empty — jsKeys not implemented?');

Prevention

When it happens

Trigger: Calling toMap() (directly or via karate logging, JSON serialization, match comparisons) on a SimpleObject implementation that does not override jsKeys().

Common situations: Logging an object that shows as {} or empty; karate.match failing because one side converts to an empty map; custom Java types exposed to JS without implementing jsKeys().

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at karate-js/src/main/java/io/karatelabs/js/SimpleObject.java:57

    String TO_STRING = "toString";

    @Override
    default void putMember(String name, Object value) {
        logger.warn("putMember() not implemented for: {} - {}", name, getClass().getName());
    }

    @Override
    default void removeMember(String name) {
        logger.warn("removeMember() not implemented for: {} - {}", name, getClass().getName());
    }

    @Override
    default Map<String, Object> toMap() {
        return toMap(jsKeys(), this);
    }

    default Collection<String> jsKeys() {
        logger.warn("jsKeys() not implemented for: {}", getClass().getName());
        return Collections.emptyList();
    }

    @Override
    default Object getMember(String name) {
        if (TO_STRING.equals(name)) {
            return jsToString();
        }
        return jsGet(name);
    }

    Object jsGet(String name);

    default JavaCallable jsToString() {
        try {
            Object temp = jsGet(TO_STRING);
            if (temp instanceof JavaCallable jsc) {
                return jsc;

View on GitHub (pinned to a22eb90246)