apache/maven · error · MavenException

The PluginContext is only available during a mojo execution

Error message

The PluginContext is only available during a mojo execution

What it means

MavenException thrown by Session.getPluginContext(project) when the container lookup of MojoExecution fails — i.e. the call happens outside a mojo execution. The plugin context is a per-plugin/per-project map that only exists while a Maven-configured mojo runs; DefaultSession derives it by looking up MojoExecution in the current Sisu scope and reading its PluginDescriptor.

Source

Thrown at impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultSession.java:193

    }

    @Nonnull
    @Override
    public List<Project> getProjects() {
        return getProjects(getMavenSession().getProjects());
    }

    @Nonnull
    @Override
    public Map<String, Object> getPluginContext(Project project) {
        requireNonNull(project, "project" + " cannot be null");
        try {
            MojoExecution mojoExecution = lookup.lookup(MojoExecution.class);
            MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
            PluginDescriptor pluginDescriptor = mojoDescriptor.getPluginDescriptor();
            return getMavenSession().getPluginContext(pluginDescriptor, ((DefaultProject) project).getProject());
        } catch (LookupException e) {
            throw new MavenException("The PluginContext is only available during a mojo execution", e);
        }
    }

    @Override
    protected Session newSession(RepositorySystemSession repoSession, List<RemoteRepository> repositories) {
        MavenSession t = getMavenSession();
        final MavenSession ms = requireNonNull(t);
        final MavenSession mss;
        if (repoSession != ms.getRepositorySession()) {
            mss = new MavenSession(repoSession, ms.getRequest(), ms.getResult());
        } else {
            mss = ms;
        }
        return newSession(mss, repositories);
    }

    protected Session newSession(MavenSession mavenSession, List<RemoteRepository> repositories) {
        return new DefaultSession(

View on GitHub (pinned to e4093d4e12)

Solutions

  1. Call getPluginContext only inside Mojo.execute(); capture the map there and pass it on explicitly
  2. For state that must outlive the execution, use your own store keyed by project instead of plugin context
  3. Guard call sites in shared utilities with a try/catch MavenException or a flag indicating mojo context

Example fix

// before: called outside a mojo execution
Map<String, Object> ctx = session.getPluginContext(project); // MavenException

// after: capture during execution, pass explicitly
public void execute() {
    Map<String, Object> ctx = getPluginContext(); // inside Mojo
    worker.accept(ctx);
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Detect mojo-execution context before calling
boolean inMojoExecution;
try {
    lookup.lookup(MojoExecution.class);
    inMojoExecution = true;
} catch (LookupException e) {
    inMojoExecution = false;
}

Try / catch

try {
    Map<String, Object> ctx = session.getPluginContext(project);
} catch (MavenException e) {
    if ("The PluginContext is only available during a mojo execution".equals(e.getMessage())) {
        ctx = Map.of(); // degrade gracefully outside executions
    } else throw e;
}

Prevention

When it happens

Trigger: Calling session.getPluginContext(...) outside Mojo#execute(): during project building, lifecycle planning, import-scope dependency resolution, or direct embedder/API use where no mojo execution scope is active (LookupException is wrapped into this MavenException).

Common situations: Mojos handing Session to background threads/work that outlives execute(); API consumers assuming Session always carries plugin state; utility code shared between mojo and non-mojo contexts calling getPluginContext unconditionally.

Related errors


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