pinpoint-apm/pinpoint · error · NullPointerException

value

Error message

value

What it means

ObjectAnnotation wraps an annotation key/value pair attached to spans. The package-private constructor rejects a null value with a NullPointerException("value") to guarantee that every annotation carries a non-null, abbreviated string value. The value is eagerly converted via value.toString() and truncated (StringUtils.abbreviate) for thread-safety, so a null has no meaningful representation.

Source

Thrown at agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/annotation/ObjectAnnotation.java:32

 * limitations under the License.
 */

package com.navercorp.pinpoint.profiler.context.annotation;

import com.navercorp.pinpoint.common.util.StringUtils;
import com.navercorp.pinpoint.profiler.context.Annotation;

/**
 * @author emeroad
 */
public class ObjectAnnotation implements Annotation<Object> {

    private final int key;
    private final String value;

    ObjectAnnotation(int key, Object value) {
        if (value == null) {
            throw new NullPointerException("value");
        }
        this.key = key;
        // Not recommended Lazy evaluation for Thread safety
        this.value = StringUtils.abbreviate(value.toString());
    }

    @Override
    public int getKey() {
        return key;
    }

    @Override
    public Object getValue() {
        return value;
    }

    @Override
    public String toString() {

View on GitHub (pinned to 744c3d3075)

Solutions

  1. Substitute a placeholder string for null before creating the annotation, e.g. Annotations.of(key, String.valueOf(value)) or "null".
  2. Skip the annotation entirely when the value is null (check before calling the factory).
  3. Add a null check/log in plugin code where the annotated value is produced to find why it is null.
  4. Wrap annotation creation in a small helper that normalizes nulls so all plugins behave consistently.

Example fix

// before
trace.recordAttribute(Annotations.of(100, possiblyNull)); // NPE
// after
if (possiblyNull != null) {
    trace.recordAttribute(Annotations.of(100, possiblyNull));
} else {
    trace.recordAttribute(Annotations.of(100, "null"));
}
Defensive patterns

Strategy: validation

Validate before calling

if (value != null) {
    trace.recordAttribute(Annotations.of(key, value));
}

Type guard

boolean isAnnotatable(Object value) {
    return value != null;
}

Try / catch

try {
    trace.recordAttribute(Annotations.of(key, value));
} catch (NullPointerException e) {
    logger.debug("Skipping annotation {} with null value", key);
}

Prevention

When it happens

Trigger: Calling the ObjectAnnotation factory/constructor with a null value — e.g. TraceValue/Annotations.of(key, null), or plugin code recording an annotation whose computed value (a method argument/return value) is null.

Common situations: Plugins annotating method parameters or return values that are legitimately null; configuration recording request attributes that are absent; dynamic values resolved lazily and coming back null at annotation time.

Related errors


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