karatelabs/karate · error · JsErrorException
cannot set . (on )
Error message
cannot set . (on )
What it means
Thrown by JavaUtils.setStatic when a JS script attempts to assign to a static field of a Java class and the reflective write fails for any reason: field doesn't exist, isn't public, is final, or the value type is incompatible. Reported as 'cannot set .<name> (on <TypeName>)'.
Solutions
- Confirm the field is a public, non-final, static, mutable field of the exact class.
- Convert the assigned value to the field's declared type (e.g. java.lang.Integer.valueOf(42)).
- Prefer setter methods or configuration APIs over direct static field mutation.
- For final fields, redesign — they cannot be legally reassigned via set().
Example fix
// before
var System = Java.type('java.lang.System');
System.out = null; // final field, fails
// after
var System = Java.type('java.lang.System');
System.setProperty('my.key', 'value'); Defensive patterns
Strategy: validation
Validate before calling
var f = Clz.getClass().getField('fieldName');
var ok = java.lang.reflect.Modifier.isStatic(f.getModifiers()) && !java.lang.reflect.Modifier.isFinal(f.getModifiers()) && java.lang.reflect.Modifier.isPublic(f.getModifiers());
if (!ok) karate.fail('field is not a public non-final static'); Try / catch
try { Clz.field = value; } catch (e) { if (String(e).indexOf('cannot set') !== -1) { Clz.setField(value); } else { throw e; } } Prevention
- Never mutate JDK/library final or constant fields
- Prefer setters or configuration APIs over direct field assignment
- Coerce the value to the field's declared type before assigning
- Treat static state changes as test-setup actions with cleanup
When it happens
Trigger: ClassName.someField = value where someField is not a public non-final static field, or where the assigned JS value cannot be stored in the field's declared type.
Common situations: Trying to mutate JDK constants (Integer.MAX_VALUE), assigning to final or system properties fields, type mismatches (string into an int field), and JPMS-restricted fields.
Related errors
- . is not a property (on )
- toBean() needs two arguments: object and class name
- object is null
- java bridge not enabled
- assignment to constant
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/3d1f1e3dd58f6fe0.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/js/JavaUtils.java:157
return method;
}
private static Method findStaticMethod(Class<?> clazz, String name) {
for (Method method : clazz.getMethods()) {
if (method.getName().equals(name) && Modifier.isStatic(method.getModifiers())
&& method.getParameterCount() == 0) {
return method;
}
}
return null;
}
static void setStatic(Class<?> clazz, String name, Object value) {
try {
Field field = clazz.getField(name);
field.set(null, value);
} catch (Exception e) {
throw JsErrorException.typeError("cannot set ." + name + " (on " + jsTypeName(clazz) + ")");
}
}
/**
* Returned by {@link #getOrNotFound} when a Java object has no member of that name — the
* <em>expected</em> outcome of a JS property read that misses, which is why it is a value
* and not an exception. Never escapes into JS: the one caller
* ({@code PropertyAccess.accessViaBridge}) turns it into {@code undefined}.
*/
static final Object NOT_FOUND = new Object();
/** A member that is a method, not a getter or field — resolved to a callable on read. */
private static final Object METHOD_MARKER = new Object();
/**
* Per-class resolution of a property name to the getter / field / method that serves it,
* or {@link #NOT_FOUND}. Every entry here — the misses above all — used to be recomputed on
* every read, and computing one costs up to three {@code Class.getMethods()} array copiesView on GitHub (pinned to a22eb90246)