alibaba/spring-ai-alibaba · warning

Extra state key collision detected: key=

Error message

Extra state key collision detected: key='{}', oldValue='{}', newValue='{}', strategy={}, mergedValue='{}'

What it means

When extracting non-core state (extra state) from each sub-graph after parallel execution, extractExtraStateFromSubGraph detects that two sub-agents wrote the same extra key. It applies the configured KeyStrategy (default REPLACE, so last writer wins) and logs this warning including old/new/merged values.

Solutions

  1. Give each sub-agent a unique outputKey so their extra state keys don't collide
  2. Configure an explicit KeyStrategy (e.g. MERGE/APPEND) for keys intentionally shared
  3. Use a dedicated ResultAggregator merge strategy that namespaces keys per sub-agent
  4. Review the logged mergedValue to confirm last-writer-wins (REPLACE) is acceptable

Example fix

// before
agentA = ReactAgent.builder().name("a").outputKey("result").build();
agentB = ReactAgent.builder().name("b").outputKey("result").build(); // collision
// after
agentA = ReactAgent.builder().name("a").outputKey("a_result").build();
agentB = ReactAgent.builder().name("b").outputKey("b_result").build();
Defensive patterns

Strategy: validation

Validate before calling

Set<String> keys = new HashSet<>();
for (Agent s : subAgents) { String k = ((ReactAgent) s).getOutputKey(); if (!keys.add(k)) { throw new IllegalStateException("Duplicate outputKey across sub-agents: " + k); } }

Prevention

When it happens

Trigger: extractExtraStateFromSubGraph (called from apply) encounters a key already present in the accumulated extraState map while merging another sub-graph's state — e.g. multiple sub-agents sharing a default output key or both writing a common key like 'summary'.

Common situations: Sub-agents configured with identical outputKeys; a shared global key written by every agent (e.g. 'messages' handled elsewhere but custom keys like 'context'); copy-pasted agent configs.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


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

Appendix: source

Thrown at spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/flow/node/EnhancedParallelResultAggregator.java:202

	 * @param subGraphState the sub-graph's complete final state map
	 * @param outputKeys all known sub-agent output keys to exclude
	 * @param extraState the map to collect extra state entries into
	 */
	private void extractExtraStateFromSubGraph(Map<String, Object> subGraphState,
											   Set<String> outputKeys,
											   Map<String, Object> extraState) {
		for (Map.Entry<String, Object> entry : subGraphState.entrySet()) {
			String key = entry.getKey();
			if (isSystemKey(key) || outputKeys.contains(key)) {
				continue;
			}
			if (extraState.containsKey(key)) {
				Object oldValue = extraState.get(key);
				Object newValue = entry.getValue();
				KeyStrategy strategy = keyStrategies.getOrDefault(key, KeyStrategy.REPLACE);
				Object mergedValue = strategy.apply(oldValue, newValue);
				extraState.put(key, mergedValue);
				logger.warn("Extra state key collision detected: key='{}', "
						+ "oldValue='{}', newValue='{}', strategy={}, mergedValue='{}'",
						key, oldValue, newValue, strategy.getClass().getSimpleName(), mergedValue);
			}
			else {
				extraState.put(key, entry.getValue());
				logger.debug("Extracted extra state from sub-graph: {} = {}", key, entry.getValue());
			}
		}
	}

	/**
	 * Determines whether a key is a system/internal key that should not be propagated.
	 * A key is considered internal if it starts with the system prefix ({@value SYSTEM_KEY_PREFIX})
	 * or is present in the hardcoded {@link #SYSTEM_STATE_KEYS} fallback set.
	 */
	private static boolean isSystemKey(String key) {
		return key.startsWith(SYSTEM_KEY_PREFIX) || SYSTEM_STATE_KEYS.contains(key);
	}

View on GitHub (pinned to f82da0b50f)