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
- Do not hand-implement or proxy Maven SPI interfaces; always obtain instances (Session, Model, services) from Maven's own lookup
- Align the Maven core / API versions between your plugin or extension and the running Maven
- 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
- Never implement or proxy Maven SPI interfaces yourself; get instances from lookup
- Keep plugin/extension Maven core versions aligned with the running Maven
- Avoid deep proxies around Session/Model objects crossing into impl code
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
- {} is null
- A maven session is already associated with the repository se
- Cannot access session scope outside of a scoping block
- No instance of ${clazz.getName()} is bound to the session sc
- Not yet implemented
AI-assisted analysis of apache/maven@e4093d4e12 (2026-08-21).
Data as JSON: /api/errors/dd21c4158e54469f.
Report an issue: GitHub.