pinpoint-apm/pinpoint · error · IllegalArgumentException

Cannot add setter to static fields. setterMethod: ${setterNa

Error message

Cannot add setter to static fields. setterMethod: ${setterName}, fieldName: ${fieldName}

What it means

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.

Source

Thrown at agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/ASMClass.java:342

    }

    @Override
    public void addSetter(Class<?> setterClass, String fieldName, boolean removeFinal) throws InstrumentException {
        Objects.requireNonNull(setterClass, "setterClass");
        try {
            final SetterAnalyzer.SetterDetails setterDetails = SetterAnalyzer.instance().analyze(setterClass);
            final ASMFieldNodeAdapter fieldNode = this.classNode.getField(fieldName, null);
            if (fieldNode == null) {
                throw new IllegalArgumentException("Not found field. name=" + fieldName);
            }

            final Type fieldType = setterDetails.getFieldType();
            if (!fieldNode.getJavaType().equals(fieldType)) {
                throw new IllegalArgumentException("Argument type of the setter is different with the field type. setterMethod: " + fieldType + ", fieldType: " + fieldNode.getJavaType());
            }

            if (fieldNode.isStatic()) {
                throw new IllegalArgumentException("Cannot add setter to static fields. setterMethod: " + setterDetails.getSetter().getName() + ", fieldName: " + fieldName);
            }

            final int original = fieldNode.getAccess();
            boolean finalRemoved = false;
            if (fieldNode.isFinal()) {
                if (!removeFinal) {
                    throw new IllegalArgumentException("Cannot add setter to final field. setterMethod: " + setterDetails.getSetter().getName() + ", fieldName: " + fieldName);
                } else {
                    final int removed = original & ~Opcodes.ACC_FINAL;
                    fieldNode.setAccess(removed);
                    finalRemoved = true;
                }
            }

            try {
                boolean modified = finalRemoved;
                modified |= this.classNode.addSetterMethod(setterDetails.getSetter().getName(), fieldNode);
                modified |= this.classNode.addInterface(setterClass.getName());

View on GitHub (pinned to 744c3d3075)

Solutions

  1. Remove 'static' from the target field or change the field name in the transform to a non-static field
  2. Rewrite the instrumentation to intercept the methods that read/write the static field instead of adding a setter
  3. Check the actual target class bytecode (javap) to confirm the field is not static before applying the transform

Example fix

// before
clazz.addSetter(setterClass, "INSTANCE"); // INSTANCE is static
// after
clazz.addSetter(setterClass, "connection"); // instance field
Defensive patterns

Strategy: validation

Validate before calling

Field f = targetClass.getDeclaredField(fieldName);
if (java.lang.reflect.Modifier.isStatic(f.getModifiers())) {
    throw new IllegalArgumentException(fieldName + " is static; setter cannot be added");
}

Type guard

boolean isInstanceField(Class<?> c, String name) {
    try { return !Modifier.isStatic(c.getField(name).getModifiers()); } catch (NoSuchFieldException e) { return false; }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07). Data as JSON: /api/errors/af3d689692b10b9e. Report an issue: GitHub.