{"record":{"id":"93789967b5e50d7b","repo":"alibaba/spring-ai-alibaba","slug":"skillregistry-cannot-be-null","errorCode":null,"errorMessage":"SkillRegistry cannot be null","messagePattern":"SkillRegistry cannot be null","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/hook/skills/DisableSkillTool.java","lineNumber":51,"sourceCode":" */\npublic class DisableSkillTool implements BiFunction<DisableSkillTool.DisableSkillRequest, ToolContext, String> {\n\n\tpublic static final String DISABLE_SKILL = \"disable_skill\";\n\n\tpublic static final String DESCRIPTION = \"\"\"\n\t\t\tDisables a skill in the current SkillRegistry instance without deleting any files.\n\t\t\t\n\t\t\tUsage:\n\t\t\t- Provide either skill_name or skill_path\n\t\t\t- If both are provided, they must refer to the same skill\n\t\t\t- Disabled skills are hidden from the current registry's listings and reads\n\t\t\t\"\"\";\n\n\tprivate final SkillRegistry skillRegistry;\n\n\tpublic DisableSkillTool(SkillRegistry skillRegistry) {\n\t\tif (skillRegistry == null) {\n\t\t\tthrow new IllegalArgumentException(\"SkillRegistry cannot be null\");\n\t\t}\n\t\tthis.skillRegistry = skillRegistry;\n\t}\n\n\tpublic static ToolCallback createDisableSkillToolCallback(SkillRegistry skillRegistry, String description) {\n\t\treturn FunctionToolCallback.builder(DISABLE_SKILL, new DisableSkillTool(skillRegistry))\n\t\t\t\t.description(description != null ? description : DESCRIPTION)\n\t\t\t\t.inputType(DisableSkillRequest.class)\n\t\t\t\t.build();\n\t}\n\n\t@Override\n\tpublic String apply(DisableSkillRequest request, ToolContext toolContext) {\n\t\tString skillName = normalize(request != null ? request.skillName : null);\n\t\tString skillPath = normalize(request != null ? request.skillPath : null);\n\t\tif (skillName == null && skillPath == null) {\n\t\t\treturn \"Error: Either skill_name or skill_path is required\";\n\t\t}","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/alibaba/spring-ai-alibaba/blob/f82da0b50f35744c13968191be2b1cd2452ef550/spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/hook/skills/DisableSkillTool.java#L33-L69","documentation":"DisableSkillTool's constructor rejects a null SkillRegistry with an IllegalArgumentException. The registry is the sole dependency this tool needs to look up and disable skills, so constructing it without one is guaranteed to fail later; the library fails fast instead.","triggerScenarios":"Calling new DisableSkillTool(null), or calling the static factory createDisableSkillToolCallback(skillRegistry, description) with a null first argument.","commonSituations":"Wiring skills into an agent where the FileSystemSkillRegistry was built conditionally (e.g. skills directory missing so the builder was skipped) and null was passed through; refactoring that removed registry initialization; Spring bean injection returning null due to a missing configuration.","solutions":["Create a SkillRegistry before building the tool, e.g. SkillRegistry registry = FileSystemSkillRegistry.builder().build();","If skills are optional, guard the registration: only add the disable-skill tool callback when a non-null registry is available.","Check the factory/wiring path (createDisableSkillToolCallback) and ensure it is never invoked with a null registry."],"exampleFix":"// before\nToolCallback cb = DisableSkillTool.createDisableSkillToolCallback(null, \"Disable a skill\");\n// after\nSkillRegistry registry = FileSystemSkillRegistry.builder().skillDirectory(skillsDir).build();\nToolCallback cb = DisableSkillTool.createDisableSkillToolCallback(registry, \"Disable a skill\");","handlingStrategy":"validation","validationCode":"if (registry == null) { throw new IllegalStateException(\"Initialize SkillRegistry before creating DisableSkillTool\"); }\nDisableSkillTool tool = new DisableSkillTool(registry);","typeGuard":"boolean hasRegistry(SkillRegistry r) { return r != null; }","tryCatchPattern":"try { tool = new DisableSkillTool(registry); } catch (IllegalArgumentException e) { log.error(\"Registry missing: {}\", e.getMessage()); }","preventionTips":["Always construct the SkillRegistry before any skill tool callbacks.","Make the registry a required constructor dependency in your wiring code.","Add an application-startup assertion that the registry bean is non-null."],"tags":["java","null-check","configuration"],"backgroundTag":"null-argument","analyzedSha":"f82da0b50f35744c13968191be2b1cd2452ef550","analyzedAt":"2026-09-09T15:32:42.421Z","contentChangedAt":"2026-09-09T15:32:42.421Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}