{"record":{"id":"a822ba410141d40b","repo":"karatelabs/karate","slug":"jskeys-not-implemented-for","errorCode":null,"errorMessage":"jsKeys() not implemented for: {}","messagePattern":"jsKeys\\(\\) not implemented for: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"karate-js/src/main/java/io/karatelabs/js/SimpleObject.java","lineNumber":57,"sourceCode":"    String TO_STRING = \"toString\";\n\n    @Override\n    default void putMember(String name, Object value) {\n        logger.warn(\"putMember() not implemented for: {} - {}\", name, getClass().getName());\n    }\n\n    @Override\n    default void removeMember(String name) {\n        logger.warn(\"removeMember() not implemented for: {} - {}\", name, getClass().getName());\n    }\n\n    @Override\n    default Map<String, Object> toMap() {\n        return toMap(jsKeys(), this);\n    }\n\n    default Collection<String> jsKeys() {\n        logger.warn(\"jsKeys() not implemented for: {}\", getClass().getName());\n        return Collections.emptyList();\n    }\n\n    @Override\n    default Object getMember(String name) {\n        if (TO_STRING.equals(name)) {\n            return jsToString();\n        }\n        return jsGet(name);\n    }\n\n    Object jsGet(String name);\n\n    default JavaCallable jsToString() {\n        try {\n            Object temp = jsGet(TO_STRING);\n            if (temp instanceof JavaCallable jsc) {\n                return jsc;","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/js/SimpleObject.java#L39-L75","documentation":"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.","triggerScenarios":"Calling toMap() (directly or via karate logging, JSON serialization, match comparisons) on a SimpleObject implementation that does not override jsKeys().","commonSituations":"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().","solutions":["If you own the Java class, implement jsKeys() to return the actual key collection (and ensure getMember works for them)","Convert the object explicitly to a Map in Java before exposing it to karate","Note that the empty result is silent data loss — check for this warning whenever an object serializes to {}"],"exampleFix":"// before\nclass MyClass implements SimpleObject { } // jsKeys() default -> empty\n// after\n@Override public Collection<String> jsKeys() { return fields.keySet(); }","handlingStrategy":"validation","validationCode":null,"typeGuard":"// verify object converts non-empty before matching\nvar asMap = karate.toJson(obj); if (Object.keys(asMap).length === 0) karate.warn('object serialized empty — jsKeys not implemented?');\n","tryCatchPattern":null,"preventionTips":["Implement jsKeys() in every custom SimpleObject class","Prefer converting Java objects to Map before exposing to JS","Watch for this warning whenever an object prints as {}"],"tags":["javascript","java-interop","serialization","empty"],"backgroundTag":"unsupported-operation","analyzedSha":"a22eb90246d958d15a47bf436693d0121ad2812d","analyzedAt":"2026-09-12T09:01:00.220Z","contentChangedAt":"2026-09-12T09:01:00.220Z","schemaVersion":2},"datasetVersion":"2026-09-19T12:17:13.211Z"}