{"record":{"id":"aedc8b25ca04deae","repo":"apache/maven","slug":"cannot-access-session-scope-outside-of-a-scoping-b","errorCode":null,"errorMessage":"Cannot access session scope outside of a scoping block","messagePattern":"Cannot access session scope outside of a scoping block","errorType":"exception","errorClass":"OutOfScopeException","httpStatus":null,"severity":"error","filePath":"impl/maven-impl/src/main/java/org/apache/maven/impl/di/SessionScope.java","lineNumber":69,"sourceCode":"        public <T> Supplier<T> scope(Key<T> key, Supplier<T> unscoped) {\n            Supplier<?> provider = provided.computeIfAbsent(key, k -> new CachingProvider<>(unscoped));\n            return (Supplier<T>) provider;\n        }\n\n        public Collection<CachingProvider<?>> providers() {\n            return provided.values();\n        }\n    }\n\n    protected final List<ScopeState> values = new CopyOnWriteArrayList<>();\n\n    public void enter() {\n        values.add(0, new ScopeState());\n    }\n\n    protected ScopeState getScopeState() {\n        if (values.isEmpty()) {\n            throw new OutOfScopeException(\"Cannot access session scope outside of a scoping block\");\n        }\n        return values.get(0);\n    }\n\n    public void exit() {\n        if (values.isEmpty()) {\n            throw new IllegalStateException();\n        }\n        values.remove(0);\n    }\n\n    public <T> void seed(Class<T> clazz, Supplier<T> value) {\n        getScopeState().seed(clazz, value);\n    }\n\n    public <T> void seed(Class<T> clazz, T value) {\n        seed(clazz, (Supplier<T>) () -> value);\n    }","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/apache/maven/blob/e4093d4e120eac99d6bdce5ba67cace2f3085c97/impl/maven-impl/src/main/java/org/apache/maven/impl/di/SessionScope.java#L51-L87","documentation":"SessionScope keeps a stack of ScopeState (enter() pushes, exit() pops). getScopeState() throws OutOfScopeException when the stack is empty — i.e. a session-scoped object was requested before enter() was called, after exit(), or from a context where the session scope was never opened. Session-scoped beans exist only while Maven has an open session scope block.","triggerScenarios":"Resolving a @SessionScoped binding in a unit test without sessionScope.enter(); resolving during container startup before the session scope opens; resolving after the scope was exited (session torn down); accessing session-scoped beans from harness code that never entered the scope.","commonSituations":"Standalone Sisu/Guice usage of Maven components outside a Maven session; tests instantiating components directly; extensions that eagerly resolve session-scoped services in constructors.","solutions":["Only resolve session-scoped beans while a session scope block is open — inside Maven's session lifecycle","In tests, bracket with sessionScope.enter(); try { ... } finally { sessionScope.exit(); }","Defer eager resolution: inject providers/suppliers and resolve lazily when the scope is guaranteed active"],"exampleFix":"// before\n@Inject MySessionBean bean; // resolved at container startup, scope not entered -> OutOfScopeException\n\n// after: lazy resolution inside the open scope\n@Inject Provider<MySessionBean> beanProvider;\nvoid duringSession() {\n    MySessionBean bean = beanProvider.get(); // scope is open here\n}","handlingStrategy":"validation","validationCode":"// open the session scope before resolving session-scoped beans\nsessionScope.enter();\ntry {\n    sessionScope.seed(Session.class, session);\n    MyBean b = injector.getInstance(MyBean.class);\n} finally {\n    sessionScope.exit();\n}","typeGuard":null,"tryCatchPattern":"try {\n    return injector.getInstance(MyBean.class);\n} catch (OutOfScopeException e) {\n    // session scope not open here: defer resolution until the session lifecycle provides the scope\n    return null; // or re-dispatch inside an open scope block\n}","preventionTips":["Open the session scope (enter/exit) around any code resolving session-scoped beans","Inject Provider<T> and resolve lazily inside the session lifecycle instead of eagerly at construction","Do not resolve session-scoped types in static init or container startup hooks"],"tags":["maven","di","sisu","scope","session"],"backgroundTag":"di-scope-not-entered","analyzedSha":"e4093d4e120eac99d6bdce5ba67cace2f3085c97","analyzedAt":"2026-08-21T22:58:24.034Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}