{"record":{"id":"f0436d609f4444bd","repo":"pinpoint-apm/pinpoint","slug":"cannot-leave-with-scope-depth-depth","errorCode":null,"errorMessage":"Cannot leave with scope. depth: ${depth}","messagePattern":"Cannot leave with scope\\. depth: (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/scope/DefaultTraceScope.java","lineNumber":53,"sourceCode":"    }\n\n    public boolean tryEnter() {\n        // policy is ALWAYS\n        depth++;\n        return true;\n    }\n\n    public boolean canLeave() {\n        if (!isActive()) {\n            return false;\n        }\n\n        return true;\n    }\n\n    public void leave() {\n        if (!isActive()) {\n            throw new IllegalStateException(\"Cannot leave with scope. depth: \" + depth);\n        }\n\n        // policy is ALWAYS\n        depth--;\n    }\n\n    @Override\n    public boolean isActive() {\n        return depth > 0;\n    }\n\n    @Override\n    public String toString() {\n        final StringBuilder sb = new StringBuilder(\"DefaultTraceScope{\");\n        sb.append(\"name='\").append(name).append('\\'');\n        sb.append(\", depth=\").append(depth);\n        sb.append('}');\n        return sb.toString();","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/pinpoint-apm/pinpoint/blob/744c3d3075e595656abb1ae331ad2c0e4c9eb996/agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/scope/DefaultTraceScope.java#L35-L71","documentation":"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.","triggerScenarios":"Calling leave() when isActive() is false — i.e. no prior enter(), or leave() called one more time than enter().","commonSituations":"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).","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"],"exampleFix":"// before\nscope.leave();\n// after\nif (scope.isActive()) {\n    scope.leave();\n}","handlingStrategy":"validation","validationCode":"if (!scope.isActive()) { throw new IllegalStateException(\"scope not active before leave\"); }","typeGuard":null,"tryCatchPattern":"try { scope.leave(); } catch (IllegalStateException e) { logger.debug(\"leave on inactive scope ignored\", e); }","preventionTips":["Guard leave() with isActive()","Use try/finally right after enter()","Ensure async completion doesn't close scope before leave"],"tags":["java","tracing","state","lifecycle"],"backgroundTag":"invalid-state-transition","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"}