apache/maven · error · OutOfScopeException

Cannot access session scope outside of a scoping block

Error message

Cannot access session scope outside of a scoping block

What it means

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.

Source

Thrown at impl/maven-impl/src/main/java/org/apache/maven/impl/di/SessionScope.java:69

        public <T> Supplier<T> scope(Key<T> key, Supplier<T> unscoped) {
            Supplier<?> provider = provided.computeIfAbsent(key, k -> new CachingProvider<>(unscoped));
            return (Supplier<T>) provider;
        }

        public Collection<CachingProvider<?>> providers() {
            return provided.values();
        }
    }

    protected final List<ScopeState> values = new CopyOnWriteArrayList<>();

    public void enter() {
        values.add(0, new ScopeState());
    }

    protected ScopeState getScopeState() {
        if (values.isEmpty()) {
            throw new OutOfScopeException("Cannot access session scope outside of a scoping block");
        }
        return values.get(0);
    }

    public void exit() {
        if (values.isEmpty()) {
            throw new IllegalStateException();
        }
        values.remove(0);
    }

    public <T> void seed(Class<T> clazz, Supplier<T> value) {
        getScopeState().seed(clazz, value);
    }

    public <T> void seed(Class<T> clazz, T value) {
        seed(clazz, (Supplier<T>) () -> value);
    }

View on GitHub (pinned to e4093d4e12)

Solutions

  1. Only resolve session-scoped beans while a session scope block is open — inside Maven's session lifecycle
  2. In tests, bracket with sessionScope.enter(); try { ... } finally { sessionScope.exit(); }
  3. Defer eager resolution: inject providers/suppliers and resolve lazily when the scope is guaranteed active

Example fix

// before
@Inject MySessionBean bean; // resolved at container startup, scope not entered -> OutOfScopeException

// after: lazy resolution inside the open scope
@Inject Provider<MySessionBean> beanProvider;
void duringSession() {
    MySessionBean bean = beanProvider.get(); // scope is open here
}
Defensive patterns

Strategy: validation

Validate before calling

// open the session scope before resolving session-scoped beans
sessionScope.enter();
try {
    sessionScope.seed(Session.class, session);
    MyBean b = injector.getInstance(MyBean.class);
} finally {
    sessionScope.exit();
}

Try / catch

try {
    return injector.getInstance(MyBean.class);
} catch (OutOfScopeException e) {
    // session scope not open here: defer resolution until the session lifecycle provides the scope
    return null; // or re-dispatch inside an open scope block
}

Prevention

When it happens

Trigger: 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.

Common situations: Standalone Sisu/Guice usage of Maven components outside a Maven session; tests instantiating components directly; extensions that eagerly resolve session-scoped services in constructors.

Related errors


AI-assisted analysis of apache/maven@e4093d4e12 (2026-08-21). Data as JSON: /api/errors/aedc8b25ca04deae. Report an issue: GitHub.