alibaba/spring-ai-alibaba · warning · IllegalStateException

Constructor did not produce a Map instance:

Error message

Constructor did not produce a Map instance: 

What it means

SerializationUtils.deepCopyMap attempts to deep-copy a Map by reflectively instantiating the original map's concrete class with a no-arg constructor. If the created instance is not a Map (or reflection fails), it falls back to HashMap after logging; the IllegalStateException is thrown when the no-arg constructor somehow produced a non-Map object — an invariant that should be impossible for a Map subclass.

Solutions

  1. Use standard Map implementations (HashMap, LinkedHashMap, TreeMap) in graph state.
  2. Remove the custom Map subclass or give it a public no-arg constructor that returns a proper Map.
  3. Wrap state values in plain collections before adding them to OverAllState.

Example fix

// before
state.put("data", new MyCustomMap<String,Object>(delegate));
// after
state.put("data", new LinkedHashMap<>(myCustomMap));
Defensive patterns

Strategy: validation

Validate before calling

Object v = state.get("data");
if (!(v instanceof HashMap || v instanceof LinkedHashMap || v instanceof TreeMap)) {
  // normalize before adding to graph state
  v = new LinkedHashMap<>((Map<String,Object>) v);
}

Type guard

boolean isCopySafeMap(Object v) {
  return v instanceof Map && v.getClass().getDeclaredConstructors().length > 0
      && v instanceof HashMap || v instanceof LinkedHashMap || v instanceof TreeMap;
}

Try / catch

try {
  Map<String,Object> copy = SerializationUtils.deepCopy(state.data());
} catch (IllegalStateException e) {
  log.warn("deepCopy failed: {}", e.getMessage());
  Map<String,Object> copy = new HashMap<>(state.data());
}

Prevention

When it happens

Trigger: Calling deepCopy (via deepCopyValue) on a state Map whose concrete class has a no-arg constructor returning a non-Map instance, or whose reflection-based instantiation path misbehaves; mainly reachable when custom Map implementations are placed into graph state.

Common situations: Users put exotic Map subclasses (e.g. wrapper/delegating maps, immutable builders) into OverAllState; classpath anomalies or bytecode tricks cause the check to fire.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09). Data as JSON: /api/errors/d6e1e558a7a34d4a. Report an issue: GitHub.

Appendix: source

Thrown at spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/utils/SerializationUtils.java:71

	 * @param original the original Map object
	 * @return the deep copied Map object, returns null if the original object is null
	 */
	@SuppressWarnings("unchecked")
	public static Map<String, Object> deepCopyMap(Map<String, Object> original) {
		if (original == null) {
			return null;
		}

		// Preserve the original Map type if it's not a standard Map implementation
		// This handles cases like fastjson2's JSONObject (which extends LinkedHashMap)
		Map<String, Object> copy;
		try {
			// Try to create an instance of the same class
			var constructor = original.getClass().getDeclaredConstructor();
			constructor.setAccessible(true);  // Handle non-public constructors
			Object instance = constructor.newInstance();
			if (!(instance instanceof Map)) {
				throw new IllegalStateException("Constructor did not produce a Map instance: " + original.getClass().getName());
			}
			copy = (Map<String, Object>) instance;
			log.debug("Successfully preserved Map type: {}", original.getClass().getName());
		} catch (Exception e) {
			// If instantiation fails, fall back to HashMap
			log.debug("Could not preserve Map type {}, falling back to HashMap: {}", 
				original.getClass().getName(), e.getMessage());
			copy = new HashMap<>();
		}
		
		for (Map.Entry<String, Object> entry : original.entrySet()) {
			copy.put(entry.getKey(), deepCopyValue(entry.getValue()));
		}
		return copy;
	}

	/**
	 * Recursively deep copy values of any type

View on GitHub (pinned to f82da0b50f)