apache/maven · error · IllegalArgumentException

{} is not an instance of {}

Error message

{} is not an instance of {}

What it means

ImplUtils.cast(clazz, object, name) throws IllegalArgumentException(name + " is not an instance of " + clazz.getName()) when the object is non-null but not of the required internal type. The Maven impl layer uses this to reject substitutes that do not carry its internal implementation class — e.g. a user-written Session implementation passed where the impl's InternalSession is required.

Source

Thrown at impl/maven-impl/src/main/java/org/apache/maven/impl/ImplUtils.java:34

 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.maven.impl;

import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

class ImplUtils {

    public static <T> T cast(Class<T> clazz, Object o, String name) {
        if (!clazz.isInstance(o)) {
            if (o == null) {
                throw new IllegalArgumentException(name + " is null");
            }
            throw new IllegalArgumentException(name + " is not an instance of " + clazz.getName());
        }
        return clazz.cast(o);
    }

    public static <U, V> List<V> map(Collection<U> list, Function<U, V> mapper) {
        return list.stream().map(mapper).filter(Objects::nonNull).collect(Collectors.toList());
    }
}

View on GitHub (pinned to e4093d4e12)

Solutions

  1. Do not hand-implement or proxy Maven SPI interfaces; always obtain instances (Session, Model, services) from Maven's own lookup
  2. Align the Maven core / API versions between your plugin or extension and the running Maven
  3. In tests, use the real objects from a bootstrapped session instead of mocks for anything crossing into the impl layer

Example fix

// before: hand-rolled Session implementation
Session mySession = new MyCustomSession();
InternalSession.from(mySession); // "is not an instance of" InternalSession

// after: use the session Maven provides
Session session = mavenExecutionRequestSession; // obtained from Maven
InternalSession.from(session);
Defensive patterns

Strategy: type-guard

Type guard

// guard before passing API objects into impl-layer code
static boolean isUsableSession(Object s) {
    return s != null && s.getClass().getName().startsWith("org.apache.maven.impl.");
    // stronger: s instanceof org.apache.maven.impl.InternalSession (impl classpath only)
}

Try / catch

try {
    InternalSession.from(session);
} catch (IllegalArgumentException e) {
    if (e.getMessage() != null && e.getMessage().contains("is not an instance of")) {
        // a wrapped/custom implementation was passed; re-fetch the real session from Maven
        throw new IllegalStateException("Use the Session provided by Maven, not a custom implementation", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Implementing org.apache.maven.api.Session (or another API interface) yourself and passing it to code that calls InternalSession.from / ImplUtils.cast; wrapping or delegating Maven objects through proxies that strip their concrete type; mixing API versions so the impl class no longer matches.

Common situations: Third-party frameworks wrapping the Maven Session in dynamic proxies; plugins compiled against a different Maven core version than the one running; partial mocks in tests replacing real Session objects.

Related errors


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