{"record":{"id":"67a12d96f12631e7","repo":"alibaba/nacos","slug":"skill-is-required","errorCode":null,"errorMessage":"Skill is required","messagePattern":"Skill is required","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":400,"severity":"error","filePath":"copilot/src/main/java/com/alibaba/nacos/copilot/form/SkillOptimizationForm.java","lineNumber":66,"sourceCode":"    /**\n     * Conversation history (optional).\n     * Contains user inputs, tool calls, and model responses.\n     */\n    private ConversationHistory conversationHistory;\n    \n    /**\n     * Target file name to optimize (optional).\n     * If specified, only optimize the content of this specific file.\n     * If not specified, optimize the entire Skill.\n     */\n    private String targetFileName;\n    \n    /**\n     * Validate form data.\n     */\n    public void validate() {\n        if (skill == null) {\n            throw new IllegalArgumentException(\"Skill is required\");\n        }\n        if (StringUtils.isBlank(skill.getName())) {\n            throw new IllegalArgumentException(\"Skill name is required\");\n        }\n    }\n    \n    public Skill getSkill() {\n        return skill;\n    }\n    \n    public void setSkill(Skill skill) {\n        this.skill = skill;\n    }\n    \n    public String getOptimizationGoal() {\n        return optimizationGoal;\n    }\n    ","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/copilot/src/main/java/com/alibaba/nacos/copilot/form/SkillOptimizationForm.java#L48-L84","documentation":"Thrown by SkillOptimizationForm.validate() (copilot module) when the `skill` field is null. This form backs the POST /v3/console/copilot/skill/optimize SSE endpoint. The entire Skill object must be present (not just non-null) because the optimizer needs the full skill structure including its name to operate.","triggerScenarios":"Posting to /v3/console/copilot/skill/optimize with the `skill` field omitted or explicitly null in the JSON body. optimizationGoal, selectedMcpTools, conversationHistory, and targetFileName are all optional.","commonSituations":"Client serializes a null skill reference. Form submitted before a skill is selected/loaded. API caller omits the skill object.","solutions":["Include a non-null `skill` object in the request body.","Ensure the skill is loaded/selected in the UI before enabling optimize.","Serialize the full Skill model (with at least a name) before posting."],"exampleFix":"// before\nbody: JSON.stringify({ skill: currentSkill, optimizationGoal })\n\n// after\nif (!currentSkill) {\n  setError('Select or load a skill to optimize');\n  return;\n}\nbody: JSON.stringify({ skill: currentSkill, optimizationGoal })","handlingStrategy":"validation","validationCode":"function hasSkill(skill: unknown): boolean {\n  return skill !== null && skill !== undefined && typeof skill === 'object';\n}","typeGuard":"function isSkillLike(value: unknown): value is { name: string } {\n  return value !== null && typeof value === 'object' && 'name' in value;\n}","tryCatchPattern":null,"preventionTips":["Include a non-null skill object in the optimize request body.","Load/select a skill in the UI before enabling optimize.","Serialize the full Skill model before posting."],"tags":["copilot","skill-optimize","java","validation","form"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}