spring-projects/spring-ai · error · IllegalArgumentException

instantiation failed

Error message

 instantiation failed

What it means

MetaUtils.getMeta reflectively invokes the no-arg constructor of a MetaProvider via Constructor.newInstance(). This error wraps InvocationTargetException, InstantiationException, or IllegalAccessException when instantiation or the constructor body fails — e.g. the constructor threw an exception, the class is abstract, or the constructor is not accessible.

Source

Thrown at mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/common/MetaUtils.java:82

	public static Map<String, Object> getMeta(Class<? extends MetaProvider> metaProviderClass) {

		if (metaProviderClass == null) {
			return null;
		}

		String className = metaProviderClass.getName();
		MetaProvider metaProvider;
		try {
			// Prefer a public no-arg constructor; fall back to a declared no-arg if
			// accessible
			Constructor<? extends MetaProvider> constructor = getConstructor(metaProviderClass);
			metaProvider = constructor.newInstance();
		}
		catch (NoSuchMethodException e) {
			throw new IllegalArgumentException("Required no-arg constructor not found in " + className, e);
		}
		catch (InvocationTargetException | InstantiationException | IllegalAccessException e) {
			throw new IllegalArgumentException(className + " instantiation failed", e);
		}

		Map<String, Object> meta = metaProvider.getMeta();
		return meta == null ? null : Collections.unmodifiableMap(meta);
	}

	/**
	 * Locate a no-argument constructor on the given class: prefer public, otherwise fall
	 * back to a declared no-arg constructor.
	 * @param metaProviderClass the class to inspect
	 * @return the resolved no-arg constructor
	 * @throws NoSuchMethodException if the class does not declare any no-arg constructor
	 */
	private static Constructor<? extends MetaProvider> getConstructor(Class<? extends MetaProvider> metaProviderClass)
			throws NoSuchMethodException {
		try {
			return metaProviderClass.getDeclaredConstructor();
		}

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Read the wrapped cause (e.getCause()) to find the real failure inside the constructor and fix it
  2. Ensure the registered class is a concrete, instantiable class, not abstract or an interface
  3. Make the no-arg constructor public
  4. Remove heavy/fragile initialization from the constructor; do it lazily in getMeta()

Example fix

// before
class MyMetaProvider implements MetaProvider {
    MyMetaProvider() { connectToRemote(); } // throws at construction
}

// after
class MyMetaProvider implements MetaProvider {
    public Map<String, Object> getMeta() {
        return Map.of("status", lookupStatus()); // no throwing ctor work
    }
}
Defensive patterns

Strategy: try-catch

Validate before calling

// instantiate eagerly at startup to fail fast
Object probe = metaProviderClass.getDeclaredConstructor().newInstance();

Try / catch

try {
    Map<String, Object> meta = MetaUtils.getMeta(providerClass);
} catch (IllegalArgumentException e) {
    Throwable cause = e.getCause();
    log.error("MetaProvider {} failed: {}", providerClass.getName(),
        cause != null ? cause.getMessage() : e.getMessage(), cause);
}

Prevention

When it happens

Trigger: A MetaProvider no-arg constructor that throws (wrapping InvocationTargetException); the registered class is abstract or an interface (InstantiationException); the constructor exists but is not public and not accessible (IllegalAccessException).

Common situations: Constructor initialization logic fails at runtime (missing env vars, failed connections); someone registers an interface or abstract base class as the provider; provider class is package-private and the module system blocks reflective access.

Related errors


AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11). Data as JSON: /api/errors/c43dedf2f5ef206d. Report an issue: GitHub.