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

  1. Only call leave() after checking isActive()
  2. Put leave() in a finally block immediately after a successful enter()
  3. Ensure the same TraceScope instance is used for enter and leave
  4. 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

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


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