alibaba/spring-ai-alibaba · error · IllegalArgumentException

Strategy type '' is already registered

Error message

Strategy type '' is already registered

What it means

Thrown by FlowGraphBuildingStrategyRegistry.registerStrategy(FlowGraphBuildingStrategy) when the strategy's getStrategyType() returns a type string that was already registered in the registry. The registry enforces one factory per type key so that createStrategy(type) is unambiguous. Duplicate registration almost always means the same strategy instance (or two strategies returning the same type string) is being registered twice, e.g. during repeated initialization or hot re-registration.

Source

Thrown at spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/flow/strategy/FlowGraphBuildingStrategyRegistry.java:69

	}

	/**
	 * Registers a new graph building strategy (same instance returned each time).
	 * @param strategy the strategy to register
	 * @throws IllegalArgumentException if strategy is null or type is already registered
	 */
	public void registerStrategy(FlowGraphBuildingStrategy strategy) {
		if (strategy == null) {
			throw new IllegalArgumentException("Strategy cannot be null");
		}

		String type = strategy.getStrategyType();
		if (type == null || type.trim().isEmpty()) {
			throw new IllegalArgumentException("Strategy type cannot be null or empty");
		}

		if (strategyFactories.containsKey(type)) {
			throw new IllegalArgumentException("Strategy type '" + type + "' is already registered");
		}

		strategyFactories.put(type, () -> strategy);
	}

	/**
	 * Registers a strategy factory. Each call to {@link #createStrategy(String)} or
	 * {@link #getStrategy(String)} will use the factory to obtain a strategy instance.
	 * @param type the strategy type
	 * @param factory the factory that creates strategy instances
	 * @throws IllegalArgumentException if type or factory is null, or type is already registered
	 */
	public void registerStrategy(String type, Supplier<FlowGraphBuildingStrategy> factory) {
		if (type == null || type.trim().isEmpty()) {
			throw new IllegalArgumentException("Strategy type cannot be null or empty");
		}
		if (factory == null) {
			throw new IllegalArgumentException("Strategy factory cannot be null");

View on GitHub (pinned to f82da0b50f)

Solutions

  1. Do not re-register an existing type; check registry.containsStrategy(type) (or try createStrategy) before registering.
  2. Use the registerStrategy(String type, Supplier) overload only for genuinely new type strings.
  3. Ensure initialization code runs once (guard with a boolean, @PostConstruct, or singleton registry).
  4. If replacement is intended, add/use an explicit unregister or replace API instead of throwing on duplicate registration.

Example fix

// before
registry.registerStrategy(myStrategy); // myStrategy.getStrategyType() == "loop" (already registered)
// after
if (!registry.containsStrategy(myStrategy.getStrategyType())) {
    registry.registerStrategy(myStrategy);
}
Defensive patterns

Strategy: validation

When it happens

Trigger: Calling registerStrategy(strategy) where strategy.getStrategyType() equals a type already present in strategyFactories; re-running an initialization block that registers built-in strategies without clearing the registry; two custom strategies accidentally sharing the same strategyType string.

Common situations: Spring bean re-creation or application context refresh invoking registry setup twice; copy-pasting a custom strategy class and forgetting to change the returned strategy type; tests constructing a fresh registry per case but reusing a singleton strategy.

Related errors


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