{"record":{"id":"da74c0138f3cdf8d","repo":"alibaba/nacos","slug":"parameter-missing-da74c0","errorCode":"PARAMETER_MISSING","errorMessage":"Request parameter `skillCard` should not be `null` or empty.","messagePattern":"Request parameter `skillCard` should not be `null` or empty\\.","errorType":"exception","errorClass":"NacosApiException","httpStatus":400,"severity":"error","filePath":"ai/src/main/java/com/alibaba/nacos/ai/form/skills/admin/SkillDetailForm.java","lineNumber":47,"sourceCode":" * @author nacos\n */\npublic class SkillDetailForm extends SkillForm {\n    \n    @Serial\n    private static final long serialVersionUID = 1L;\n    \n    /**\n     * Skill card JSON string, contains complete Skill information.\n     */\n    private String skillCard;\n    \n    @Override\n    public void validate() throws NacosApiException {\n        fillDefaultNamespaceId();\n        // For create/detail, skillName is optional (can be in skillCard)\n        // Only skillCard is required\n        if (StringUtils.isEmpty(skillCard)) {\n            throw new NacosApiException(NacosException.INVALID_PARAM, ErrorCode.PARAMETER_MISSING,\n                \"Request parameter `skillCard` should not be `null` or empty.\");\n        }\n    }\n    \n    public String getSkillCard() {\n        return skillCard;\n    }\n    \n    public void setSkillCard(String skillCard) {\n        this.skillCard = skillCard;\n    }\n}\n","sourceCodeStart":29,"sourceCodeEnd":60,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/ai/src/main/java/com/alibaba/nacos/ai/form/skills/admin/SkillDetailForm.java#L29-L60","documentation":"SkillDetailForm.validate() requires a non-empty `skillCard` JSON string for create/detail operations. The skillCard carries the complete Skill object (name, description, content, etc.); without it the server has nothing to create or show. Unlike SkillForm, skillName is OPTIONAL here because the name can live inside the skillCard itself. The check uses StringUtils.isEmpty, so null or empty-string both fail.","triggerScenarios":"Calling the skill create or detail-submit API without the `skillCard` field, or with skillCard=\"\". Triggered when the client sends skillName separately but no card body.","commonSituations":"Frontend that splits skill fields into individual form params instead of assembling the skillCard JSON; sending the card under a different field name (e.g. `skill`, `payload`); JSON serialization producing an empty string due to a null object.","solutions":["Assemble the full Skill object and serialize it to the `skillCard` field as a JSON string.","Ensure the Skill object has at least a `name`; the name may also be read from the card.","If forking from an existing version instead of creating new, use SkillDraftCreateForm with basedOnVersion (which does NOT require skillCard)."],"exampleFix":"// before\n{\"skillName\":\"my-skill\"}\n// after\n{\"skillCard\":\"{\\\"name\\\":\\\"my-skill\\\",\\\"description\\\":\\\"...\\\",\\\"content\\\":\\\"...\\\"}\"}","handlingStrategy":"validation","validationCode":"// Before calling skill create/detail-submit\nif (skillCard == null || skillCard.isEmpty()) {\n    throw new IllegalArgumentException(\"skillCard JSON is required\");\n}\n// also ensure the card parses and has a name\nSkill parsed = SkillRequestUtil.parseSkill(form);\nif (parsed.getName() == null || parsed.getName().isBlank()) {\n    throw new IllegalArgumentException(\"skillCard must contain a name\");\n}","typeGuard":"// TypeScript — assemble card client-side\nconst buildSkillCard = (s: { name: string; content: string }): string =>\n  JSON.stringify(s);\nconst isValidCard = (json: string): boolean => {\n  try { const o = JSON.parse(json); return !!o?.name; } catch { return false; }\n};","tryCatchPattern":"try {\n    form.validate();\n} catch (NacosApiException e) {\n    // skillCard missing — assemble the full Skill JSON and retry\n}","preventionTips":["Assemble the entire Skill object into skillCard JSON; do not send scattered fields.","If forking, switch to SkillDraftCreateForm with basedOnVersion (no skillCard needed).","Validate the card has a non-blank name before serializing."],"tags":["validation","skill-api","required-field","skill-card","json"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}