pinpoint-apm/pinpoint · warning
Duplicated {} scope={}
Error message
Duplicated {} scope={} What it means
WARN from AsyncScopeUtils.nested() when trace.addScope(scopeName) returns a non-null old scope, meaning an async scope with the same name already exists on this trace — the async trace block was entered re-entrantly or the scope was leaked by a previous unmatched begin/end. The code treats this as nesting and returns true so the caller can skip re-initialization; a commented-out deleteAsyncTrace indicates the old corrupted-trace cleanup is disabled, so the trace may carry stale state.
Source
Thrown at agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/AsyncScopeUtils.java:19
package com.navercorp.pinpoint.profiler.context;
import com.navercorp.pinpoint.bootstrap.context.Trace;
import com.navercorp.pinpoint.bootstrap.context.scope.TraceScope;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public final class AsyncScopeUtils {
private static final Logger logger = LogManager.getLogger(AsyncScopeUtils.class);
private AsyncScopeUtils() {
}
public static boolean nested(Trace trace, String scopeName) {
// add async scope.
final TraceScope oldScope = trace.addScope(scopeName);
if (oldScope != null) {
if (logger.isWarnEnabled()) {
logger.warn("Duplicated {} scope={}", trace.getClass().getSimpleName(), oldScope.getName());
}
// delete corrupted trace.
// deleteAsyncTrace(trace);
return true;
} else {
if (logger.isDebugEnabled()) {
logger.debug("start {} scope", trace.getClass().getSimpleName());
}
}
return false;
}
}
View on GitHub (pinned to 744c3d3075)
Solutions
- Ensure every async trace block begin has exactly one matching end on the same trace.
- Use a unique scope name per logical async unit instead of a shared constant across re-entrant calls.
- Do not reuse a single Trace across concurrent async continuations; each continuation should get its own async trace.
- If you see this repeatedly, check the installed plugin versions for known double-entry bugs and upgrade the agent.
Example fix
// before
AsyncScopeUtils.nested(trace, "MY_ASYNC"); // called again for same trace
// after
if (AsyncScopeUtils.nested(trace, "MY_ASYNC")) {
return; // skip duplicate scope entry
} Defensive patterns
Strategy: validation
Validate before calling
// before entering an async scope, ensure it is not already active
final TraceScope scope = trace.getScope(scopeName);
if (scope != null) {
// scope already exists; skip addScope / nested entry
} Prevention
- Pair every async scope begin with exactly one end on the same Trace.
- Use distinct scope names per async unit to avoid re-entrant collisions.
- Never share one Trace object across concurrent async tasks.
When it happens
Trigger: Entering the same async scope twice on one trace: e.g. calling the async trace begin API twice without a matching end, or async callbacks sharing a single Trace object concurrently.
Common situations: Async instrumentation (CompletableFuture/executor plugins) where a callback is executed twice or a span event's traceBlockEnd is missed; custom plugins reusing one scope name per trace.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Corrupted call stack found TraceRoot:{}, CallStack:{}
- BracketMatcherOperator is not an operation target.
- unsupported type:
- ${name} define fail Caused by:${e.getMessage()}
- traceReference is null
AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07).
Data as JSON: /api/errors/3206be156703e9e9.
Report an issue: GitHub.