pinpoint-apm/pinpoint · error · InstrumentException

Failed to add field with accessor

Error message

Failed to add field with accessor [${accessorClassName}]. Cause:${e.getMessage()}

What it means

Catch-all guard in ASMClass.addField(accessor): an unexpected exception occurred while injecting the accessor-backed field into the class bytecode; the message prefixes the accessor class name and chains the underlying cause.

Solutions

  1. Inspect the chained cause message for the real bytecode-generation failure
  2. Verify the accessor type class is loadable and valid
  3. Check for duplicate field injection on classes like CGLIB proxies (already handled — confirm not hitting a variant)
  4. Upgrade the profiler if hitting a known instrumentation bug
Defensive patterns

Strategy: try-catch

When it happens

Trigger: Thrown at agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/ASMClass.java:289 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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

Appendix: source

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

            final String accessorTypeName = accessorClass.getName();
            final String fieldName = FIELD_PREFIX + JavaAssistUtils.javaClassNameToVariableName(accessorTypeName);
            // skip members already declared in this class. e.g. a CGLIB proxy copies the injected members of an instrumented class
            boolean modified = false;
            ASMFieldNodeAdapter fieldNode = this.classNode.getDeclaredField(fieldName, type.getDescriptor());
            if (fieldNode == null) {
                fieldNode = this.classNode.addField(fieldName, type.getDescriptor());
                modified = true;
            }
            modified |= this.classNode.addInterface(accessorTypeName);
            modified |= this.classNode.addGetterMethod(accessorDetails.getGetter().getName(), fieldNode);
            modified |= this.classNode.addSetterMethod(accessorDetails.getSetter().getName(), fieldNode);
            if (modified) {
                setModified(true);
            } else if (logger.isDebugEnabled()) {
                logger.debug("Skip addField, accessor already declared. class={}, accessor={}", getName(), accessorTypeName);
            }
        } catch (Exception e) {
            throw new InstrumentException("Failed to add field with accessor [" + accessorClass.getName() + "]. Cause:" + e.getMessage(), e);
        }
    }

    @Override
    public void addGetter(Class<?> getterClass, String fieldName) throws InstrumentException {
        Objects.requireNonNull(getterClass, "getterClass");
        Objects.requireNonNull(fieldName, "fieldName");

        try {
            final GetterAnalyzer.GetterDetails getterDetails = GetterAnalyzer.instance().analyze(getterClass);
            final ASMFieldNodeAdapter fieldNode = this.classNode.getField(fieldName, null);
            if (fieldNode == null) {
                throw new IllegalArgumentException("Not found field. name=" + fieldName);
            }
            Type fieldType = getterDetails.getFieldType();
            if (!fieldNode.getJavaType().equals(fieldType)) {
                throw new IllegalArgumentException("different return type. return=" + fieldType + ", field=" + fieldNode.getJavaType());
            }

View on GitHub (pinned to 744c3d3075)