pinpoint-apm/pinpoint · error · IllegalStateException
Cannot leave with scope. depth: ${depth}
Error message
Cannot leave with scope. depth: ${depth} What it means
DefaultTraceScope.leave() throws IllegalStateException when the scope is not active (depth <= 0), meaning leave() was called without a matching enter() or more times than enter() was called. The scope tracks a depth counter; leaving an inactive scope is an unbalanced enter/leave pair.
Source
Thrown at agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/scope/DefaultTraceScope.java:53
}
public boolean tryEnter() {
// policy is ALWAYS
depth++;
return true;
}
public boolean canLeave() {
if (!isActive()) {
return false;
}
return true;
}
public void leave() {
if (!isActive()) {
throw new IllegalStateException("Cannot leave with scope. depth: " + depth);
}
// policy is ALWAYS
depth--;
}
@Override
public boolean isActive() {
return depth > 0;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("DefaultTraceScope{");
sb.append("name='").append(name).append('\'');
sb.append(", depth=").append(depth);
sb.append('}');
return sb.toString();View on GitHub (pinned to 744c3d3075)
Solutions
- Only call leave() after checking isActive()
- Put leave() in a finally block immediately after a successful enter()
- Ensure the same TraceScope instance is used for enter and leave
- Check that async trace completion isn't closing the scope before leave() runs
Example fix
// before
scope.leave();
// after
if (scope.isActive()) {
scope.leave();
} Defensive patterns
Strategy: validation
Validate before calling
if (!scope.isActive()) { throw new IllegalStateException("scope not active before leave"); } Try / catch
try { scope.leave(); } catch (IllegalStateException e) { logger.debug("leave on inactive scope ignored", e); } Prevention
- Guard leave() with isActive()
- Use try/finally right after enter()
- Ensure async completion doesn't close scope before leave
When it happens
Trigger: Calling leave() when isActive() is false — i.e. no prior enter(), or leave() called one more time than enter().
Common situations: Interceptors that call leave on an error path where enter was never reached, or leave() invoked after the trace scope already closed (async trace completed).
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- startTime not recorded
- cannot leave with BOUNDARY trace scope. depth: ${depth}
- UNSUPPORTED_OPERATION
- spanEventList is empty.
- first SpanEvent is null
AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07).
Data as JSON: /api/errors/f0436d609f4444bd.
Report an issue: GitHub.