{"record":{"id":"0417a4597b8782cd","repo":"alibaba/spring-ai-alibaba","slug":"skillregistry-must-be-provided-use-skillsagenthoo","errorCode":null,"errorMessage":"SkillRegistry must be provided. Use SkillsAgentHook to load skills.","messagePattern":"SkillRegistry must be provided\\. Use SkillsAgentHook to load skills\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/interceptor/skills/SkillsInterceptor.java","lineNumber":112,"sourceCode":" * {@value ReadSkillTool#READ_SKILL}. For each such call, the <i>skill_name</i> argument is recorded.\n * Tools from {@link #getGroupedTools()} for those skill names are then added to the request's\n * {@link ModelRequest#getDynamicToolCallbacks() dynamicToolCallbacks}.\n */\npublic class SkillsInterceptor extends ModelInterceptor {\n\n\tprivate static final Logger logger = LoggerFactory.getLogger(SkillsInterceptor.class);\n\n\tprivate final SkillRegistry skillRegistry;\n\n\tprivate final Map<String, List<ToolCallback>> groupedTools;\n\n\tprivate final Supplier<Map<String, List<ToolCallback>>> groupedToolsSupplier;\n\n\tprivate final ToolCallbackResolver toolCallbackResolver;\n\n\tprivate SkillsInterceptor(Builder builder) {\n\t\tif (builder.skillRegistry == null) {\n\t\t\tthrow new IllegalArgumentException(\"SkillRegistry must be provided. Use SkillsAgentHook to load skills.\");\n\t\t}\n\t\tthis.skillRegistry = builder.skillRegistry;\n\t\tthis.groupedTools = builder.groupedTools != null\n\t\t\t\t? builder.groupedTools\n\t\t\t\t: Collections.emptyMap();\n\t\tthis.groupedToolsSupplier = builder.groupedToolsSupplier;\n\t\tthis.toolCallbackResolver = builder.toolCallbackResolver;\n\t}\n\n\tpublic static Builder builder() {\n\t\treturn new Builder();\n\t}\n\n\t@Override\n\tpublic ModelResponse interceptModel(ModelRequest request, ModelCallHandler handler) {\n\t\tList<SkillMetadata> skills = skillRegistry.listAll();\n\n\t\tif (skills.isEmpty()) {","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/alibaba/spring-ai-alibaba/blob/f82da0b50f35744c13968191be2b1cd2452ef550/spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/interceptor/skills/SkillsInterceptor.java#L94-L130","documentation":"SkillsInterceptor's private constructor requires a non-null SkillRegistry. The interceptor has nothing to resolve skills against without one, so building without a registry throws IllegalArgumentException and points you to SkillsAgentHook as the intended way to load skills.","triggerScenarios":"Building a SkillsInterceptor via its Builder without calling the method that sets skillRegistry (or passing null), instead of using SkillsAgentHook to populate it.","commonSituations":"Manually constructing the interceptor instead of going through SkillsAgentHook; registry wiring removed during refactor; conditional registration where the hook never ran.","solutions":["Use SkillsAgentHook to load and register skills, which supplies the SkillRegistry","Pass a non-null SkillRegistry to the SkillsInterceptor Builder before build()","Check that the hook that populates the registry actually executed before interceptor creation"],"exampleFix":"// before\nSkillsInterceptor.builder().build(); // no skillRegistry\n// after\nnew SkillsAgentHook(registryPath).register();\nSkillsInterceptor.builder().skillRegistry(registry).build();","handlingStrategy":"validation","validationCode":"if (registry == null) { throw new IllegalStateException(\"SkillRegistry not initialized; run SkillsAgentHook first\"); }\nSkillsInterceptor.builder().skillRegistry(registry).build();","typeGuard":null,"tryCatchPattern":"try { interceptor = SkillsInterceptor.builder().build(); } catch (IllegalArgumentException e) { throw new IllegalStateException(\"Wire SkillsAgentHook before SkillsInterceptor\", e); }","preventionTips":["Always register skills through SkillsAgentHook","Construct interceptors after hook initialization in app lifecycle","Add a startup check asserting the registry bean is non-null"],"tags":["skills","missing-dependency","config","initialization"],"backgroundTag":"missing-required-argument","analyzedSha":"f82da0b50f35744c13968191be2b1cd2452ef550","analyzedAt":"2026-09-09T15:32:42.421Z","contentChangedAt":"2026-09-09T15:32:42.421Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}