{"record":{"id":"4a7554f8c15d070a","repo":"pinpoint-apm/pinpoint","slug":"beforetrace","errorCode":null,"errorMessage":"beforeTrace:{}","messagePattern":"beforeTrace:(.+?)","errorType":"console","errorClass":"PinpointException","httpStatus":null,"severity":"error","filePath":"agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultTraceFactory.java","lineNumber":105,"sourceCode":"        return trace;\n    }\n\n\n    @Override\n    public Trace continueTraceObject(Trace trace) {\n        final Reference<Trace> reference = checkAndGet();\n\n        bind(reference, trace);\n        return trace;\n    }\n\n    private Reference<Trace> checkAndGet() {\n        final Reference<Trace> reference = this.threadLocalBinder.get();\n        final Trace old = reference.get();\n        if (old != null) {\n            final PinpointException exception = new PinpointException(\"already Trace Object exist.\");\n            if (logger.isWarnEnabled()) {\n                logger.warn(\"beforeTrace:{}\", old, exception);\n            }\n            throw exception;\n        }\n        return reference;\n    }\n\n    @Override\n    public Trace newTraceObject() {\n        final Reference<Trace> reference = checkAndGet();\n        final Trace trace = this.baseTraceFactory.newTraceObject();\n\n        bind(reference, trace);\n        return trace;\n    }\n\n    @Override\n    public Trace newTraceObject(String urlPath) {\n        final Reference<Trace> reference = checkAndGet();","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/pinpoint-apm/pinpoint/blob/744c3d3075e595656abb1ae331ad2c0e4c9eb996/agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultTraceFactory.java#L87-L123","documentation":"DefaultTraceFactory.checkAndGet() logs 'beforeTrace:{}' (with the stale Trace and a PinpointException 'already Trace Object exist.') and then throws when the thread-local trace reference already holds a non-null Trace before binding a new one. The library enforces at most one active trace per thread; this error means a previous trace was never removed from the thread-local slot.","triggerScenarios":"Calling newTraceObject/currentTraceObject creation while a prior Trace for the same thread was never closed or detached; an exception path that skipped the trace cleanup; interceptor chains starting a new trace without releasing the old one.","commonSituations":"Exceptions in instrumented code that bypass the end-side interceptor which normally nulls the thread-local; leaked traces from previous requests on pooled/reused threads (servlet containers, thread pools); plugin bugs failing to close traces.","solutions":["Ensure every created trace is closed even on exception paths (try/finally around the instrumented region)","Check for leaked traces from earlier requests on the same pooled thread; fix the code that skips trace detachment","Clear/patch the thread-local binder: upgrade the pinpoint agent if cleanup-on-exception bugs are fixed in newer versions","Inspect the logged 'beforeTrace' object to identify which code path created the stale trace"],"exampleFix":"// before\nTrace trace = traceContext.newTraceObject();\ndoRiskyWork(); // throws -> trace never closed, thread-local stays bound\ntrace.close();\n// after\nTrace trace = traceContext.newTraceObject();\ntry {\n    doRiskyWork();\n} finally {\n    trace.close(); // detaches from thread-local\n}","handlingStrategy":"try-catch","validationCode":"// before creating a new trace, verify the thread-local is free\nif (traceContext.currentTraceObject() != null) { logger.warn(\"stale trace on thread\"); }","typeGuard":"boolean threadTraceFree(TraceContext ctx) { return ctx.currentTraceObject() == null; }","tryCatchPattern":"try { trace = traceContext.newTraceObject(); } catch (PinpointException e) { logger.warn(\"thread-local trace already bound\", e); }","preventionTips":["Always close created traces in finally blocks","Beware pooled threads carrying stale thread-locals between requests","Fix plugins that start traces without guaranteed detachment","Check the logged beforeTrace to find the leaking code path"],"tags":["java","thread-local","trace-leak","pinpoint-profiler"],"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-17T15:17:12.973Z"}