spring-projects/spring-framework · error · IllegalStateException

Should be able to clone object of type [{}]: {}

Error message

Should be able to clone object of type [{}]: {}

What it means

Thrown as IllegalStateException by ReflectiveMethodInvocation.invocableClone when super.clone() throws CloneNotSupportedException. ReflectiveMethodInvocation implements Cloneable, so this should be unreachable for the base class; it fires only if a subclass drops the Cloneable interface or overrides clone() to forbid cloning. The framework treats it as an invariant violation.

Source

Thrown at spring-aop/src/main/java/org/springframework/aop/framework/ReflectiveMethodInvocation.java:235

	 * current interceptor index.
	 * @see java.lang.Object#clone()
	 */
	@Override
	public MethodInvocation invocableClone(@Nullable Object... arguments) {
		// Force initialization of the user attributes Map,
		// for having a shared Map reference in the clone.
		if (this.userAttributes == null) {
			this.userAttributes = new HashMap<>();
		}

		// Create the MethodInvocation clone.
		try {
			ReflectiveMethodInvocation clone = (ReflectiveMethodInvocation) clone();
			clone.arguments = arguments;
			return clone;
		}
		catch (CloneNotSupportedException ex) {
			throw new IllegalStateException(
					"Should be able to clone object of type [" + getClass() + "]: " + ex);
		}
	}


	@Override
	public void setUserAttribute(String key, @Nullable Object value) {
		if (value != null) {
			if (this.userAttributes == null) {
				this.userAttributes = new HashMap<>();
			}
			this.userAttributes.put(key, value);
		}
		else {
			if (this.userAttributes != null) {
				this.userAttributes.remove(key);
			}
		}

View on GitHub (pinned to 69bf83ad71)

Solutions

  1. Ensure any custom subclass of ReflectiveMethodInvocation implements Cloneable (or does not override clone() to throw).
  2. Avoid overriding clone() in your MethodInvocation subclass; let the base Object.clone() shallow-copy work.
  3. If using a third-party integration that subclasses ReflectiveMethodInvocation, upgrade it or report that Cloneable must be preserved.

Example fix

// before
class MyInvocation extends ReflectiveMethodInvocation { // no Cloneable
  @Override protected Object clone() throws CloneNotSupportedException { throw new CloneNotSupportedException(); }
}

// after
class MyInvocation extends ReflectiveMethodInvocation implements Cloneable {
  // inherit clone() from Object; do not throw
}
Defensive patterns

Strategy: type-guard

Validate before calling

Class<?> c = invocation.getClass();
if (!Cloneable.class.isAssignableFrom(c) || ReflectiveMethodInvocation.class.isAssignableFrom(c) == false) {
  // ensure custom subclasses implement Cloneable before invoking clone-dependent interceptors
}

Type guard

static boolean cloneableInvocation(Object o) {
  return o instanceof Cloneable && o instanceof ReflectiveMethodInvocation;
}

Try / catch

try { MethodInvocation clone = invocation.invocableClone(); }
catch (IllegalStateException e) {
  if (e.getMessage().contains("Should be able to clone")) { /* ensure Cloneable on subclass */ }
  throw e;
}

Prevention

When it happens

Trigger: A custom subclass of ReflectiveMethodInvocation that does not implement Cloneable, or overrides Object.clone() to throw. invocableClone() is called by interceptors that need to re-enter the chain (e.g. concurrent retries, concurrency throttle interceptors).

Common situations: Custom MethodInvocation implementations used with interceptors that rely on invocableClone(); framework integrations (Pitchfork and similar) that subclass ReflectiveMethodInvocation without preserving Cloneable.

Related errors


AI-assisted analysis of spring-projects/spring-framework@69bf83ad71 (2026-08-09). Data as JSON: /api/errors/5fee871d6edb3ac5. Report an issue: GitHub.