karatelabs/karate · error · JsErrorException
Reflect.ownKeys called on non-object
Error message
Reflect.ownKeys called on non-object
What it means
`Reflect.ownKeys(target)` implements [[OwnPropertyKeys]] and, per spec, requires an Object target. Karate's `ownKeys` throws this TypeError when the first argument is missing or not an ObjectLike (a string, number, null, undefined, etc.).
Solutions
- Pass an actual object: `Reflect.ownKeys(obj)`.
- Guard beforehand: `if (target && typeof target === 'object') Reflect.ownKeys(target)`.
- For primitives, use `Object.keys(Object(primitive))` semantics explicitly if that's the intent.
Example fix
// before const keys = Reflect.ownKeys(maybeObject); // may be undefined // after const keys = maybeObject != null && typeof maybeObject === 'object' ? Reflect.ownKeys(maybeObject) : [];
Defensive patterns
Strategy: type-guard
Validate before calling
function ownKeysSafe(target) {
if (target == null || (typeof target !== 'object' && typeof target !== 'function')) return [];
return Reflect.ownKeys(target);
} Type guard
function isReflectTarget(v) { return v != null && (typeof v === 'object' || typeof v === 'function'); } Try / catch
try { return Reflect.ownKeys(target); } catch (e) { if (e instanceof TypeError && /ownKeys called on non-object/.test(e.message)) return []; throw e; } Prevention
- Validate dynamic targets before reflective calls.
- Coerce primitives explicitly with Object(v) if reflection is intended.
- Check for undefined coming from failed lookups upstream.
When it happens
Trigger: `Reflect.ownKeys()` with no args; `Reflect.ownKeys('abc')`, `Reflect.ownKeys(42)`, `Reflect.ownKeys(null)`; passing a Java-side non-object value into the JS call.
Common situations: Reflected/introspective code fed by dynamic data where the value unexpectedly became a primitive; forwarding undefined from an earlier failed lookup.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Promise resolver is not a function
- Reflect.construct: target is not a constructor
- Reflect.construct: newTarget is not a constructor
- Reflect.construct: bad context
- Reflect.apply: target is not callable
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/1b05a9d602ac90a8.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/js/JsReflect.java:52
class JsReflect extends JsObject {
@Override
protected Object resolveOwnIntrinsic(String name) {
return switch (name) {
case "construct" -> (JsCallable) this::construct;
case "apply" -> (JsCallable) this::apply;
case "ownKeys" -> (JsCallable) this::ownKeys;
default -> null;
};
}
private static final List<String> INTRINSIC_NAMES = List.of("construct", "apply", "ownKeys");
/** §28.1.11 — [[OwnPropertyKeys]] in spec order: string keys, then the
* symbol values from the object's symbol store. */
private Object ownKeys(Context context, Object[] args) {
if (args.length < 1 || !(args[0] instanceof ObjectLike target)) {
throw JsErrorException.typeError("Reflect.ownKeys called on non-object");
}
// §10.1.11.1 OrdinaryOwnPropertyKeys: integer indices ascending, then
// strings in insertion order — the same helper Object.keys uses.
// named half only for an array — toMap()'s index keys include holes,
// and the spec index+length key set for arrays is a separate gap here
List<Object> keys = new java.util.ArrayList<>(JsObject.orderedOwnKeys(
target instanceof JsArray ja ? ja.namedPropsView().keySet() : target.toMap().keySet()));
if (target instanceof JsObject jo) {
keys.addAll(jo.ownSymbols());
}
return new JsArray(keys);
}
@Override
protected Iterable<String> ownIntrinsicNames() {
return INTRINSIC_NAMES;
}
View on GitHub (pinned to a22eb90246)