karatelabs/karate · error · JsErrorException
Object.defineProperties called on non-object
Error message
Object.defineProperties called on non-object
What it means
Object.defineProperties(target, props) requires the target to be an object (ObjectLike or Map). Passing a primitive (number, string, boolean, null, undefined) as the first argument throws this TypeError instead of implicitly wrapping.
Solutions
- Pass an actual object: Object.defineProperties({}, props)
- Coerce explicitly with Object(target) if you want wrapper semantics
- Validate the target before the call: if (target && typeof target === 'object')
- Fix the upstream source so the variable actually holds an object
Example fix
// before
Object.defineProperties(someValue, { x: { value: 1 } }); // throws if primitive
// after
const target = (someValue && typeof someValue === 'object') ? someValue : {};
Object.defineProperties(target, { x: { value: 1 } }); Defensive patterns
Strategy: validation
Validate before calling
if (target == null || (typeof target !== 'object' && typeof target !== 'function')) throw new TypeError('defineProperties target must be an object'); Type guard
function isDefinePropertiesTarget(t) { return t != null && (typeof t === 'object' || typeof t === 'function'); } Try / catch
try { Object.defineProperties(target, props); } catch (e) { if (String(e.message).includes('non-object')) target = {}; /* retry */ else throw e; } Prevention
- Assert object-ness of targets at API boundaries
- Fix upstream producers that return primitives where objects are expected
- Parse JSON payloads before passing them as targets
When it happens
Trigger: Object.defineProperties(42, {...}), Object.defineProperties('str', {...}), Object.defineProperties(null, {...}) — any non-object first argument.
Common situations: Variable that was expected to be an object but is a primitive; API returning a string/number where an object was assumed; forgetting to parse JSON before calling.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- argumentsList must be an iterable object
- assignment to constant
- assignment to constant
- called on null or undefined
- Cannot add property , object is not extensible
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/78bb148329194e50.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/js/JsObjectConstructor.java:881
// accessor support so {@code Object.defineProperty(Foo.prototype,
// "x", {get: …})} works — instances inheriting from the prototype
// resolve the accessor via the chain walk in PropertyAccess.
p.defineOwnAccessor(key, getter, setter, attrs);
}
// Other ObjectLikes (Map, raw List, etc.) don't model accessor
// descriptors. No reachable test path exercises that today.
}
private static byte ownAttrs(Object obj, String key) {
if (obj instanceof JsObject jo) return jo.getOwnAttrs(key);
if (obj instanceof JsArray ja) return ja.getOwnAttrs(key);
if (obj instanceof Prototype p) return p.getOwnAttrs(key);
return JsObject.ATTRS_DEFAULT;
}
private Object defineProperties(Context context, Object[] args) {
if (args.length < 1 || !(args[0] instanceof ObjectLike || args[0] instanceof Map)) {
throw JsErrorException.typeError("Object.defineProperties called on non-object");
}
Object source = args.length < 2 ? null : args[1];
if (source == null || source == Terms.UNDEFINED) {
throw JsErrorException.typeError("Cannot convert undefined or null to object");
}
// Spec ToObject(primitive) yields a wrapper. Boolean / number / empty
// string wrappers have no enumerable own keys, so the loop iterates
// nothing and returns the target — {@code ownKeys} below returns an
// empty set for those. A non-empty string wrapper exposes indexed
// characters as own properties; reading the first character and
// running ToPropertyDescriptor on it lands on TypeError ("Property
// descriptor must be an object"). Short-circuit that here rather
// than wiring full wrapper iteration.
if (source instanceof String s && !s.isEmpty()) {
throw JsErrorException.typeError("Property descriptor must be an object");
}
// Spec §20.1.2.3 walks enumerable own keys via [[OwnPropertyKeys]] +
// [[GetOwnProperty]], reading each descriptor via [[Get]] so accessorView on GitHub (pinned to a22eb90246)