apache/maven · error · IllegalStateException

A maven session is already associated with the repository se

Error message

A maven session is already associated with the repository session

What it means

InternalSession.associate stores the Maven Session inside the RepositorySystemSession's data map using set-if-absent semantics (rsession.getData().set(InternalSession.class, null, ...)). If a binding is already present the call returns false and IllegalStateException is thrown: one repository session can carry at most one Maven session.

Source

Thrown at impl/maven-impl/src/main/java/org/apache/maven/impl/InternalSession.java:64

import static org.apache.maven.impl.ImplUtils.cast;

public interface InternalSession extends Session {

    static InternalSession from(Session session) {
        if (session instanceof InternalSession is) {
            return is;
        }
        return cast(InternalSession.class, session, "session should be an " + InternalSession.class);
    }

    static InternalSession from(org.eclipse.aether.RepositorySystemSession session) {
        return cast(InternalSession.class, session.getData().get(InternalSession.class), "session");
    }

    static void associate(org.eclipse.aether.RepositorySystemSession rsession, Session session) {
        if (!rsession.getData().set(InternalSession.class, null, from(session))) {
            throw new IllegalStateException("A maven session is already associated with the repository session");
        }
    }

    /**
     * Executes and optionally caches a request using the provided supplier function. If caching is enabled
     * for this session, the result will be cached and subsequent identical requests will return the cached
     * value without re-executing the supplier.
     *
     * @param <REQ> The request type
     * @param <REP> The response type
     * @param req The request object used as the cache key
     * @param supplier The function to execute and cache the result
     * @return The result from the supplier (either fresh or cached)
     * @throws RuntimeException Any exception thrown by the supplier will be cached and re-thrown on subsequent calls
     */
    <REQ extends Request<?>, REP extends Result<REQ>> REP request(REQ req, Function<REQ, REP> supplier);

    <REQ extends Request<?>, REP extends Result<REQ>> List<REP> requests(

View on GitHub (pinned to e4093d4e12)

Solutions

  1. Create a fresh RepositorySystemSession (or a copy via new DefaultRepositorySystemSession(existing) with its own session data) for every Maven session you associate
  2. Associate exactly once, at bootstrap, and reuse the associated Maven session afterwards
  3. Check rsession.getData().get(InternalSession.class) before associating if the session's history is unknown

Example fix

// before: one shared repo session, associated per build
for (Build b : builds) {
    InternalSession.associate(sharedRepoSession, mavenSessionFor(b)); // IllegalStateException on 2nd pass
}

// after: fresh repo session data per build
for (Build b : builds) {
    DefaultRepositorySystemSession rss = new DefaultRepositorySystemSession(sharedRepoSession);
    InternalSession.associate(rss, mavenSessionFor(b));
}
Defensive patterns

Strategy: validation

Validate before calling

// associate only when the repository session has no binding yet
if (rsession.getData().get(InternalSession.class) != null) {
    // already associated: reuse it or start from a fresh session copy
    rsession = new DefaultRepositorySystemSession(rsession); // new data map
}
InternalSession.associate(rsession, mavenSession);

Try / catch

try {
    InternalSession.associate(rsession, session);
} catch (IllegalStateException e) {
    // repository session already carries a Maven session: create detached session data and retry
    DefaultRepositorySystemSession fresh = new DefaultRepositorySystemSession(rsession);
    InternalSession.associate(fresh, session);
    rsession = fresh;
}

Prevention

When it happens

Trigger: Calling associate(repositorySession, mavenSession) twice with the same repository session; in embedded setups, creating a new Maven Session per build while reusing a shared/singleton RepositorySystemSession.

Common situations: IDE integrations and test harnesses that repeatedly bootstrap Maven against one long-lived repository session; frameworks wrapping Maven executions in loops without resetting session state.

Related errors


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