alibaba/spring-ai-alibaba · error · IllegalArgumentException

SkillRegistry must be provided. Use FileSystemSkillRegistry.

Error message

SkillRegistry must be provided. Use FileSystemSkillRegistry.builder() to create one.

What it means

SkillsAgentHook's private Builder-based constructor requires builder.skillRegistry to be non-null. The hook wires together read/search/disable skill tools that all need the registry, so it refuses to build without one and points you at FileSystemSkillRegistry.builder() as the intended way to create it.

Source

Thrown at spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/hook/skills/SkillsAgentHook.java:93

 * }</pre>
 */
@HookPositions(HookPosition.BEFORE_AGENT)
public class SkillsAgentHook extends AgentHook {

	private static final Logger logger = LoggerFactory.getLogger(SkillsAgentHook.class);

	private final SkillRegistry skillRegistry;
	private final boolean autoReload;
	private final Map<String, List<ToolCallback>> groupedTools;
	private final Supplier<Map<String, List<ToolCallback>>> groupedToolsSupplier;
	private final ToolCallbackResolver toolCallbackResolver;
	private final ToolCallback readSkillTool;
	private final ToolCallback searchSkillsTool;
	private final ToolCallback disableSkillTool;

	private SkillsAgentHook(Builder builder) {
		if (builder.skillRegistry == null) {
			throw new IllegalArgumentException("SkillRegistry must be provided. Use FileSystemSkillRegistry.builder() to create one.");
		}
		this.skillRegistry = builder.skillRegistry;
		this.autoReload = builder.autoReload;
		this.groupedTools = builder.groupedTools != null ? builder.groupedTools : Collections.emptyMap();
		this.groupedToolsSupplier = builder.groupedToolsSupplier;
		this.toolCallbackResolver = builder.toolCallbackResolver;
		this.readSkillTool = ReadSkillTool.createReadSkillToolCallback(
				this.skillRegistry,
				ReadSkillTool.DESCRIPTION
		);
		this.searchSkillsTool = SearchSkillsTool.createSearchSkillsToolCallback(
				this.skillRegistry,
				SearchSkillsTool.DESCRIPTION
		);
		this.disableSkillTool = DisableSkillTool.createDisableSkillToolCallback(
				this.skillRegistry,
				DisableSkillTool.DESCRIPTION
		);

View on GitHub (pinned to f82da0b50f)

Solutions

  1. Add .skillRegistry(FileSystemSkillRegistry.builder().build()) to the builder chain before build().
  2. Point the FileSystemSkillRegistry builder at your skills directory and pass the result into the hook.
  3. If skills are optional, wrap hook creation in a check so it is only built when a registry is available.

Example fix

// before
SkillsAgentHook hook = SkillsAgentHook.builder().build();
// after
SkillsAgentHook hook = SkillsAgentHook.builder()
    .skillRegistry(FileSystemSkillRegistry.builder().skillDirectory(skillsDir).build())
    .build();
Defensive patterns

Strategy: validation

Validate before calling

SkillRegistry registry = FileSystemSkillRegistry.builder().skillDirectory(skillsDir).build();
SkillsAgentHook hook = SkillsAgentHook.builder().skillRegistry(registry).build();

Type guard

boolean hookReady(SkillsAgentHook.Builder b) { return b != null; } // set skillRegistry before build()

Try / catch

try { hook = SkillsAgentHook.builder().skillRegistry(registry).build(); } catch (IllegalArgumentException e) { log.error("Skills hook disabled: {}", e.getMessage()); }

Prevention

When it happens

Trigger: Calling SkillsAgentHook.builder().build() without invoking .skillRegistry(...), or passing an explicitly null registry to the builder.

Common situations: Fluent-builder chains where the registry step was omitted; assuming the hook auto-creates a registry from a default directory (it does not); conditional config that nulls out the registry.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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