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

  1. Pass an actual object: Object.defineProperties({}, props)
  2. Coerce explicitly with Object(target) if you want wrapper semantics
  3. Validate the target before the call: if (target && typeof target === 'object')
  4. 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

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


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 accessor

View on GitHub (pinned to a22eb90246)