{"record":{"id":"faa44986aba7ac1c","repo":"pinpoint-apm/pinpoint","slug":"tracereference-is-null-faa449","errorCode":null,"errorMessage":"traceReference is null","messagePattern":"traceReference is null","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DisableAsyncContext.java","lineNumber":65,"sourceCode":"\n    private Trace newAsyncContextTrace(Reference<Trace> reference) {\n        final Trace asyncTrace = local.asyncTraceContext().continueDisableAsyncContextTraceObject(traceRoot);\n        bind(reference, asyncTrace);\n\n        if (logger.isDebugEnabled()) {\n            logger.debug(\"asyncTraceContext.continueDisableAsyncContextTraceObject() AsyncTrace:{}\", asyncTrace);\n        }\n\n        if (AsyncScopeUtils.nested(asyncTrace, ASYNC_TRACE_SCOPE)) {\n            return null;\n        }\n\n        return asyncTrace;\n    }\n\n    private void bind(Reference<Trace> reference, Trace asyncTrace) {\n        if (reference.get() != null) {\n            throw new IllegalStateException(\"traceReference is null\");\n        }\n        reference.set(asyncTrace);\n    }\n\n    @Override\n    public Trace currentAsyncTraceObject() {\n        final Reference<Trace> reference = local.binder().get();\n        return reference.get();\n    }\n\n    @Override\n    public void close() {\n        local.binder().remove();\n    }\n\n\n    @Override\n    public boolean finish() {","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/pinpoint-apm/pinpoint/blob/744c3d3075e595656abb1ae331ad2c0e4c9eb996/agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DisableAsyncContext.java#L47-L83","documentation":"DisableAsyncContext.bind() throws IllegalStateException('traceReference is null') when binding an async trace into a Reference that already holds a non-null value (message is misleading). It enforces the invariant that the async trace slot is empty before binding.","triggerScenarios":"newAsyncContextTrace flow on DisableAsyncContext reaching bind(reference, asyncTrace) while reference.get() != null — the slot was already bound to another trace.","commonSituations":"Double-binding of async traces when sampling is disabled; lifecycle races reusing an already-bound reference; plugin code calling currentAsyncTraceObject repeatedly without closing traces.","solutions":["Bind each async trace to a fresh Reference","Close/complete the previous async trace before rebinding","Check for duplicate newAsyncContextTrace calls","Upgrade to a fixed pinpoint version"],"exampleFix":"// before\nbind(reference, asyncTrace); // throws if reference already set\n// after\nif (reference.get() == null) {\n    reference.set(asyncTrace);\n} else {\n    asyncTrace.close();\n}","handlingStrategy":"try-catch","validationCode":"if (reference.get() != null) {\n    // already bound; do not bind again\n}","typeGuard":"boolean canBind(Reference<Trace> ref) {\n    return ref.get() == null;\n}","tryCatchPattern":"try {\n    disableAsyncContext.bind(reference, asyncTrace);\n} catch (IllegalStateException e) {\n    logger.warn(\"reference already bound in DisableAsyncContext\", e);\n}","preventionTips":["Check reference.get() before binding","Ensure async traces are closed before reuse","Avoid caching AsyncContext across requests"],"tags":["async","trace","lifecycle","concurrency"],"backgroundTag":"internal-invariant-violation","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"}