karatelabs/karate · error · JsErrorException (typeError)
unexpected set [null]
Error message
unexpected set [null]:${value} on: ${object} What it means
An internal TypeError raised by Karate's setByName when the property name argument is null — i.e. an assignment whose target name could not be resolved to a string key. This is an invariant guard: normal `obj.x = v` syntax always supplies a name, so hitting it means the engine tried to write through a malformed/unresolved property reference (e.g. a computed key that evaluated to null in an internal path).
Solutions
- Inspect the assignment expression in the feature/script and ensure the property key resolves to a non-null string (e.g. `obj[expr] = v` where `expr` must not be null).
- Add a fallback for computed keys: `* def key = expr || 'defaultKey'` before `obj[key] = value`.
- If calling the engine API directly, assert the name is non-null before calling setByName / update.
- Report upstream if it occurs with plain syntax — it indicates an internal invariant violation.
Example fix
// before (key may be null) * eval obj[someKey] = 5 // after * def safeKey = someKey || 'fallback' * eval obj[safeKey] = 5
Defensive patterns
Strategy: validation
Validate before calling
// before dynamic writes if (key == null) key = 'defaultKey';
Type guard
function safeKey(k) { return (k != null && typeof k === 'string') ? k : String(k); } Prevention
- Never assign via computed keys that can be null.
- Coerce/null-check dynamic property names before writes.
- If calling engine APIs directly, assert arguments before setByName/update.
When it happens
Trigger: A property-set operation routed into setByName with name == null: internal path where a computed/member key resolves to null, or a bridge/Embedded JS integration calling setByName programmatically with a null key.
Common situations: Rare in hand-written features; typically seen from custom JS engine extensions, external bridge integrations, or dynamic property writes where a key expression produced null instead of a string.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- unexpected logical-assignment operator
- unexpected operator
- cannot set
- Unable to resolve global `this`
- Invalid ignore
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/4d908b8946bdcd6c.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/js/PropertyAccess.java:1142
* when {@code Array.prototype.{push, unshift}} stores at index 0), routes
* {@code length} through {@code JsArray.handleLengthAssign} for the spec
* Uint32 + writable + partial-truncate dance, and otherwise falls through
* to {@code putMember}. Package-private so {@code JsArrayPrototype.{push,
* unshift}} can do per-item Set in the spec sequence.
*/
static void setByName(Object object, String name, Object value, CoreContext context, Node trackingNode) {
setByName(object, name, value, context, trackingNode, object);
}
/** Receiver-aware variant for super references (§10.1.9 OrdinarySet with a
* distinct receiver): the accessor lookup walks {@code object}'s chain —
* the super base — but a setter runs with {@code receiver} as its
* {@code this}, and a data write creates/updates the property on
* {@code receiver}, never on the shared prototype. All non-super callers
* pass {@code object} itself via the delegating overload above. */
static void setByName(Object object, String name, Object value, CoreContext context, Node trackingNode, Object receiver) {
if (name == null) {
throw JsErrorException.typeError("unexpected set [null]:" + value + " on: " + object);
}
if (object == null) {
context.update(name, value, trackingNode);
} else if (object instanceof ObjectLike objectLike) {
// Spec ArraySetLength dispatch needs context for valueOf/toString
// coercion; route through the JsArray-specific entry point.
// Throws RangeError on invalid Uint32; silently ignores writable=false
// and partial-truncate failures (lenient mode — strict-mode TypeError
// flip lives elsewhere).
if (objectLike instanceof JsArray ja && "length".equals(name)) {
Object oldLen = ja.size();
ja.handleLengthAssign(value, context);
firePropertySet(context, name, ja.size(), oldLen, object, trackingNode);
return;
}
// If an accessor descriptor lives at `name` anywhere in the
// prototype chain, invoke its setter via slot.write —
// bypassing putMember preserves the descriptor and threadsView on GitHub (pinned to a22eb90246)