karatelabs/karate · error · JsErrorException
Property descriptor must be an object
Error message
Property descriptor must be an object
What it means
The third argument to Object.defineProperty must be a property descriptor object. Passing null or undefined as the descriptor throws this TypeError, per the spec's ToPropertyDescriptor which requires an Object.
Solutions
- Provide a valid descriptor object, e.g. {value: ..., writable: true, enumerable: true, configurable: true}
- Default an empty descriptor: desc ?? {value: undefined, writable: true, configurable: true}
- Fix the descriptor lookup that returned null/undefined
Example fix
// before
const desc = descriptors[key]; // may be undefined
Object.defineProperty(obj, key, desc); // throws
// after
const desc = descriptors[key] ?? {value: undefined, writable: true, enumerable: true, configurable: true};
Object.defineProperty(obj, key, desc); Defensive patterns
Strategy: validation
Validate before calling
if (desc == null) throw new TypeError('descriptor object required before defineProperty'); Type guard
function isDescriptor(d) { return d != null && typeof d === 'object'; } Try / catch
try { Object.defineProperty(obj, key, desc); }
catch (e) { if (String(e).includes('descriptor must be an object')) { Object.defineProperty(obj, key, desc ?? {}); } else { throw e; } } Prevention
- Default missing descriptors to {} or a full data descriptor
- Validate lookups that build descriptors dynamically
- Never pass undefined/null as the third argument even in quick scripts
When it happens
Trigger: Object.defineProperty(obj, 'x', null), Object.defineProperty(obj, 'x', undefined), or a descriptor variable that failed to initialize (e.g. descriptors[key] returned undefined).
Common situations: Building descriptors dynamically from a lookup table with missing entries; API responses where the descriptor field is null; calling with only two arguments in a loosely-typed script.
Related errors
- Object.defineProperty called on non-object
- Invalid property descriptor. Cannot both specify accessors…
- NoSuchElementException
- groupBy called with null or undefined items
- cannot destructure
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/05ff8b0174f274ad.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/js/JsObjectConstructor.java:556
/** Returns the own {@link AccessorSlot} at {@code key} when one exists,
* {@code null} otherwise (own data property, missing, or unsupported
* type). Scoped to own properties only — for the chain-walking variant
* see {@code PropertyAccess#findAccessorInChain}. */
private static AccessorSlot ownAccessorSlot(Object obj, String key) {
PropertySlot s = PropertyAccess.ownSlot(obj, key);
return s instanceof AccessorSlot acc ? acc : null;
}
@SuppressWarnings("unchecked")
Object defineProperty(Context context, Object[] args) {
if (args.length < 1 || !(args[0] instanceof ObjectLike || args[0] instanceof Map)) {
throw JsErrorException.typeError("Object.defineProperty called on non-object");
}
if (args.length < 2) {
throw JsErrorException.typeError("property key is null");
}
if (args.length < 3 || args[2] == null || args[2] == Terms.UNDEFINED) {
throw JsErrorException.typeError("Property descriptor must be an object");
}
// Spec ToPropertyKey: pass ctx so ObjectLike keys dispatch through
// ToPrimitive(string) → ToString (test262 Object/defineProperty/
// 15.2.3.6-2-{20,24,25,39,41,43,44,45,46,47,48} pass arrays / boxed
// booleans / objects with overridden toString as the key arg).
CoreContext keyCtx = context instanceof CoreContext c ? c : null;
String prop = Terms.toPropertyKey(args[1], keyCtx);
Object desc = args[2];
ObjectLike descObj;
Map<String, Object> descMap;
if (desc instanceof ObjectLike ol) {
descObj = ol;
descMap = ol.toMap();
} else if (desc instanceof Map) {
descObj = null;
descMap = (Map<String, Object>) desc;
} else {
throw JsErrorException.typeError("Property descriptor must be an object");View on GitHub (pinned to a22eb90246)