{"record":{"id":"af3d689692b10b9e","repo":"pinpoint-apm/pinpoint","slug":"cannot-add-setter-to-static-fields-settermethod","errorCode":null,"errorMessage":"Cannot add setter to static fields. setterMethod: ${setterName}, fieldName: ${fieldName}","messagePattern":"Cannot add setter to static fields\\. setterMethod: (.+?), fieldName: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/ASMClass.java","lineNumber":342,"sourceCode":"    }\n\n    @Override\n    public void addSetter(Class<?> setterClass, String fieldName, boolean removeFinal) throws InstrumentException {\n        Objects.requireNonNull(setterClass, \"setterClass\");\n        try {\n            final SetterAnalyzer.SetterDetails setterDetails = SetterAnalyzer.instance().analyze(setterClass);\n            final ASMFieldNodeAdapter fieldNode = this.classNode.getField(fieldName, null);\n            if (fieldNode == null) {\n                throw new IllegalArgumentException(\"Not found field. name=\" + fieldName);\n            }\n\n            final Type fieldType = setterDetails.getFieldType();\n            if (!fieldNode.getJavaType().equals(fieldType)) {\n                throw new IllegalArgumentException(\"Argument type of the setter is different with the field type. setterMethod: \" + fieldType + \", fieldType: \" + fieldNode.getJavaType());\n            }\n\n            if (fieldNode.isStatic()) {\n                throw new IllegalArgumentException(\"Cannot add setter to static fields. setterMethod: \" + setterDetails.getSetter().getName() + \", fieldName: \" + fieldName);\n            }\n\n            final int original = fieldNode.getAccess();\n            boolean finalRemoved = false;\n            if (fieldNode.isFinal()) {\n                if (!removeFinal) {\n                    throw new IllegalArgumentException(\"Cannot add setter to final field. setterMethod: \" + setterDetails.getSetter().getName() + \", fieldName: \" + fieldName);\n                } else {\n                    final int removed = original & ~Opcodes.ACC_FINAL;\n                    fieldNode.setAccess(removed);\n                    finalRemoved = true;\n                }\n            }\n\n            try {\n                boolean modified = finalRemoved;\n                modified |= this.classNode.addSetterMethod(setterDetails.getSetter().getName(), fieldNode);\n                modified |= this.classNode.addInterface(setterClass.getName());","sourceCodeStart":324,"sourceCodeEnd":360,"githubUrl":"https://github.com/pinpoint-apm/pinpoint/blob/744c3d3075e595656abb1ae331ad2c0e4c9eb996/agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/ASMClass.java#L324-L360","documentation":"Pinpoint's ASMClass.addSetter() validates that the field targeted by an @TargetField-style setter is not static before weaving the setter bytecode. Static fields cannot be written through instance setter methods, so the instrumentation engine rejects the request with IllegalArgumentException. The message reports the setter method name and the field name to identify the offending transformation request.","triggerScenarios":"Calling addSetter/setter API (via addSetter on ASMClass) where the field matched by the field name in the target class is declared static. The field name resolves to a fieldNode whose isStatic() is true at weave time.","commonSituations":"Instrumenting a plugin that targets a field in a library class where the field is static (e.g. singleton holders); a plugin written for one library version continues onto a newer version where the field became static; copy-pasted transform code targeting the wrong field.","solutions":["Remove 'static' from the target field or change the field name in the transform to a non-static field","Rewrite the instrumentation to intercept the methods that read/write the static field instead of adding a setter","Check the actual target class bytecode (javap) to confirm the field is not static before applying the transform"],"exampleFix":"// before\nclazz.addSetter(setterClass, \"INSTANCE\"); // INSTANCE is static\n// after\nclazz.addSetter(setterClass, \"connection\"); // instance field","handlingStrategy":"validation","validationCode":"Field f = targetClass.getDeclaredField(fieldName);\nif (java.lang.reflect.Modifier.isStatic(f.getModifiers())) {\n    throw new IllegalArgumentException(fieldName + \" is static; setter cannot be added\");\n}","typeGuard":"boolean isInstanceField(Class<?> c, String name) {\n    try { return !Modifier.isStatic(c.getField(name).getModifiers()); } catch (NoSuchFieldException e) { return false; }\n}","tryCatchPattern":null,"preventionTips":["Check field modifiers with javap before writing transforms","Prefer method interceptors over field setters for static state","Test plugin transforms against the exact target library version"],"tags":["java","bytecode-instrumentation","static-field"],"backgroundTag":"unsupported-operation","analyzedSha":"744c3d3075e595656abb1ae331ad2c0e4c9eb996","analyzedAt":"2026-09-07T18:48:45.289Z","contentChangedAt":"2026-09-07T18:48:45.289Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}