{"record":{"id":"487b5156c2d50265","repo":"apache/maven","slug":"a-maven-session-is-already-associated-with-the-rep","errorCode":null,"errorMessage":"A maven session is already associated with the repository session","messagePattern":"A maven session is already associated with the repository session","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"impl/maven-impl/src/main/java/org/apache/maven/impl/InternalSession.java","lineNumber":64,"sourceCode":"\nimport static org.apache.maven.impl.ImplUtils.cast;\n\npublic interface InternalSession extends Session {\n\n    static InternalSession from(Session session) {\n        if (session instanceof InternalSession is) {\n            return is;\n        }\n        return cast(InternalSession.class, session, \"session should be an \" + InternalSession.class);\n    }\n\n    static InternalSession from(org.eclipse.aether.RepositorySystemSession session) {\n        return cast(InternalSession.class, session.getData().get(InternalSession.class), \"session\");\n    }\n\n    static void associate(org.eclipse.aether.RepositorySystemSession rsession, Session session) {\n        if (!rsession.getData().set(InternalSession.class, null, from(session))) {\n            throw new IllegalStateException(\"A maven session is already associated with the repository session\");\n        }\n    }\n\n    /**\n     * Executes and optionally caches a request using the provided supplier function. If caching is enabled\n     * for this session, the result will be cached and subsequent identical requests will return the cached\n     * value without re-executing the supplier.\n     *\n     * @param <REQ> The request type\n     * @param <REP> The response type\n     * @param req The request object used as the cache key\n     * @param supplier The function to execute and cache the result\n     * @return The result from the supplier (either fresh or cached)\n     * @throws RuntimeException Any exception thrown by the supplier will be cached and re-thrown on subsequent calls\n     */\n    <REQ extends Request<?>, REP extends Result<REQ>> REP request(REQ req, Function<REQ, REP> supplier);\n\n    <REQ extends Request<?>, REP extends Result<REQ>> List<REP> requests(","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/apache/maven/blob/e4093d4e120eac99d6bdce5ba67cace2f3085c97/impl/maven-impl/src/main/java/org/apache/maven/impl/InternalSession.java#L46-L82","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Create a fresh RepositorySystemSession (or a copy via new DefaultRepositorySystemSession(existing) with its own session data) for every Maven session you associate","Associate exactly once, at bootstrap, and reuse the associated Maven session afterwards","Check rsession.getData().get(InternalSession.class) before associating if the session's history is unknown"],"exampleFix":"// before: one shared repo session, associated per build\nfor (Build b : builds) {\n    InternalSession.associate(sharedRepoSession, mavenSessionFor(b)); // IllegalStateException on 2nd pass\n}\n\n// after: fresh repo session data per build\nfor (Build b : builds) {\n    DefaultRepositorySystemSession rss = new DefaultRepositorySystemSession(sharedRepoSession);\n    InternalSession.associate(rss, mavenSessionFor(b));\n}","handlingStrategy":"validation","validationCode":"// associate only when the repository session has no binding yet\nif (rsession.getData().get(InternalSession.class) != null) {\n    // already associated: reuse it or start from a fresh session copy\n    rsession = new DefaultRepositorySystemSession(rsession); // new data map\n}\nInternalSession.associate(rsession, mavenSession);","typeGuard":null,"tryCatchPattern":"try {\n    InternalSession.associate(rsession, session);\n} catch (IllegalStateException e) {\n    // repository session already carries a Maven session: create detached session data and retry\n    DefaultRepositorySystemSession fresh = new DefaultRepositorySystemSession(rsession);\n    InternalSession.associate(fresh, session);\n    rsession = fresh;\n}","preventionTips":["Give each Maven session its own RepositorySystemSession (or a copy with fresh session data)","Associate exactly once at bootstrap and pass the pair around together","In long-lived embedders, audit for shared/singleton repository sessions before re-entry"],"tags":["maven","internal-api","session","state","embedding"],"backgroundTag":"duplicate-session-binding","analyzedSha":"e4093d4e120eac99d6bdce5ba67cace2f3085c97","analyzedAt":"2026-08-21T22:58:24.034Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}