{"record":{"id":"7b93e0885537d8ec","repo":"alibaba/nacos","slug":"parameter-validate-error-7b93e0","errorCode":"PARAMETER_VALIDATE_ERROR","errorMessage":"skillCard is invalid. Can't be parsed.","messagePattern":"skillCard is invalid\\. Can't be parsed\\.","errorType":"validation","errorClass":"NacosApiException","httpStatus":400,"severity":"error","filePath":"ai/src/main/java/com/alibaba/nacos/ai/utils/SkillRequestUtil.java","lineNumber":147,"sourceCode":"    /**\n     * Parse Skill request form to {@link Skill}.\n     *\n     * @param skillDetailForm skill detail form.\n     * @return skill\n     * @throws NacosApiException if parse failed or request parameter is conflicted.\n     */\n    public static Skill parseSkill(SkillDetailForm skillDetailForm) throws NacosApiException {\n        try {\n            Skill result =\n                JacksonUtils.toObj(skillDetailForm.getSkillCard(), new TypeReference<>() {\n                });\n            validateSkill(result);\n            return result;\n        } catch (NacosDeserializationException e) {\n            LOGGER\n                .error(String.format(\"Deserialize %s from %s failed, \", Skill.class.getSimpleName(),\n                    skillDetailForm.getSkillCard()), e);\n            throw new NacosApiException(NacosApiException.INVALID_PARAM,\n                ErrorCode.PARAMETER_VALIDATE_ERROR,\n                \"skillCard is invalid. Can't be parsed.\");\n        }\n    }\n    \n    /**\n     * Validate skill is legal.\n     *\n     * @param skill skill\n     * @throws NacosApiException if skill is illegal.\n     */\n    public static void validateSkill(Skill skill) throws NacosApiException {\n        validateSkillField(\"name\", skill.getName());\n        validateSkillField(\"description\", skill.getDescription());\n        validateSkillMarkdownBody(\"skillCard.skillMd\", skill.getSkillMd());\n    }\n    \n    /**","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/ai/src/main/java/com/alibaba/nacos/ai/utils/SkillRequestUtil.java#L129-L165","documentation":"Thrown by SkillRequestUtil.parseSkill when JacksonUtils.toObj fails to deserialize the skillCard JSON string from SkillDetailForm into a Skill object. The catch block intercepts NacosDeserializationException and converts it to a PARAMETER_VALIDATE_ERROR with HTTP 400, telling the caller the skillCard field is not valid JSON or does not match the Skill schema.","triggerScenarios":"POST/PUT to a skill create or update endpoint (admin or console) where the skillCard form field contains malformed JSON (unbalanced braces, trailing commas, wrong types), is not JSON at all (e.g. raw markdown or plain text), or has a structure that does not map to the Skill type's expected fields.","commonSituations":"Frontend sends skillCard as a form-encoded string with unescaped quotes breaking JSON; developer passes raw YAML frontmatter instead of JSON; Content-Type negotiation causes the form parser to deliver a truncated or double-encoded skillCard; a copy-paste from a markdown file is submitted where JSON was expected.","solutions":["Validate that skillCard is parseable JSON before submitting — use JSON.parse(skillCard) in the browser or Jackson ObjectMapper.readValue in Java.","Ensure the skillCard JSON object has the correct top-level fields: name (string), description (string), skillMd (string), and optionally version, namespaceId, resource.","Check for common JSON errors: trailing commas, unescaped quotes inside string values, missing closing braces.","If building skillCard programmatically, use JacksonUtils.toJson(skillObject) rather than string concatenation."],"exampleFix":"// before — hand-crafted JSON string with a trailing comma\nString skillCard = \"{\\\"name\\\":\\\"my-skill\\\",\\\"description\\\":\\\"test\\\",\\\"skillMd\\\":\\\"---\\\\nname: my-skill\\\\n---\\\\n# Body\\\",}\";\n\n// after — build via Jackson to guarantee valid JSON\nObjectNode node = JacksonUtils.createInstance().createObjectNode();\nnode.put(\"name\", \"my-skill\");\nnode.put(\"description\", \"test\");\nnode.put(\"skillMd\", \"---\\nname: my-skill\\n---\\n# Body\");\nString skillCard = JacksonUtils.toJson(node);","handlingStrategy":"validation","validationCode":"// Validate skillCard is valid JSON matching Skill schema before sending\ntry {\n    Skill parsed = JacksonUtils.toObj(skillCardJson, Skill.class);\n} catch (Exception e) {\n    throw new IllegalArgumentException(\"skillCard is not valid JSON: \" + e.getMessage());\n}","typeGuard":"public static boolean isValidSkillCardJson(String skillCard) {\n    if (StringUtils.isBlank(skillCard)) return false;\n    try {\n        JacksonUtils.toObj(skillCard, Skill.class);\n        return true;\n    } catch (Exception e) {\n        return false;\n    }\n}","tryCatchPattern":"try {\n    Skill skill = SkillRequestUtil.parseSkill(skillDetailForm);\n} catch (NacosApiException e) {\n    if (ErrorCode.PARAMETER_VALIDATE_ERROR.equals(e.getErrDetail())) {\n        return ResponseEntity.badRequest().body(\"Invalid skillCard JSON: \" + e.getErrMsg());\n    }\n    throw e;\n}","preventionTips":["Always build skillCard JSON using a JSON serializer (Jackson) rather than string concatenation.","Validate JSON parseability client-side before form submission.","Use a JSON linter on the skillCard string to catch syntax errors early.","When copy-pasting skillCard content, verify it is JSON (not YAML or markdown)."],"tags":["skill","json-deserialization","parameter-validation","skillcard"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}