{"record":{"id":"3d1f1e3dd58f6fe0","repo":"karatelabs/karate","slug":"cannot-set-on","errorCode":null,"errorMessage":"cannot set . (on )","messagePattern":"cannot set \\. \\(on \\)","errorType":"exception","errorClass":"JsErrorException","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/js/JavaUtils.java","lineNumber":157,"sourceCode":"        return method;\n    }\n\n    private static Method findStaticMethod(Class<?> clazz, String name) {\n        for (Method method : clazz.getMethods()) {\n            if (method.getName().equals(name) && Modifier.isStatic(method.getModifiers())\n                    && method.getParameterCount() == 0) {\n                return method;\n            }\n        }\n        return null;\n    }\n\n    static void setStatic(Class<?> clazz, String name, Object value) {\n        try {\n            Field field = clazz.getField(name);\n            field.set(null, value);\n        } catch (Exception e) {\n            throw JsErrorException.typeError(\"cannot set .\" + name + \" (on \" + jsTypeName(clazz) + \")\");\n        }\n    }\n\n    /**\n     * Returned by {@link #getOrNotFound} when a Java object has no member of that name — the\n     * <em>expected</em> outcome of a JS property read that misses, which is why it is a value\n     * and not an exception. Never escapes into JS: the one caller\n     * ({@code PropertyAccess.accessViaBridge}) turns it into {@code undefined}.\n     */\n    static final Object NOT_FOUND = new Object();\n\n    /** A member that is a method, not a getter or field — resolved to a callable on read. */\n    private static final Object METHOD_MARKER = new Object();\n\n    /**\n     * Per-class resolution of a property name to the getter / field / method that serves it,\n     * or {@link #NOT_FOUND}. Every entry here — the misses above all — used to be recomputed on\n     * every read, and computing one costs up to three {@code Class.getMethods()} array copies","sourceCodeStart":139,"sourceCodeEnd":175,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/js/JavaUtils.java#L139-L175","documentation":"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>)'.","triggerScenarios":"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.","commonSituations":"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.","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()."],"exampleFix":"// before\nvar System = Java.type('java.lang.System');\nSystem.out = null; // final field, fails\n// after\nvar System = Java.type('java.lang.System');\nSystem.setProperty('my.key', 'value');","handlingStrategy":"validation","validationCode":"var f = Clz.getClass().getField('fieldName');\nvar ok = java.lang.reflect.Modifier.isStatic(f.getModifiers()) && !java.lang.reflect.Modifier.isFinal(f.getModifiers()) && java.lang.reflect.Modifier.isPublic(f.getModifiers());\nif (!ok) karate.fail('field is not a public non-final static');","typeGuard":null,"tryCatchPattern":"try { Clz.field = value; } catch (e) { if (String(e).indexOf('cannot set') !== -1) { Clz.setField(value); } else { throw e; } }","preventionTips":["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"],"tags":["javascript","java-interop","static-field","assignment"],"backgroundTag":"java-member-not-accessible","analyzedSha":"a22eb90246d958d15a47bf436693d0121ad2812d","analyzedAt":"2026-09-12T09:01:00.220Z","contentChangedAt":"2026-09-12T09:01:00.220Z","schemaVersion":2},"datasetVersion":"2026-09-16T19:17:19.609Z"}