{"record":{"id":"5f02589324e2a160","repo":"alibaba/nacos","slug":"parameter-validate-error-5f0258","errorCode":"PARAMETER_VALIDATE_ERROR","errorMessage":"Unsupported ARD artifact resourceType: \" + resourceType","messagePattern":"Unsupported ARD artifact resourceType: \" \\+ resourceType","errorType":"exception","errorClass":"NacosApiException","httpStatus":400,"severity":"error","filePath":"ai-registry-adaptor/src/main/java/com/alibaba/nacos/airegistry/service/ard/ArdArtifactService.java","lineNumber":92,"sourceCode":"        String version, String mcpName) throws NacosException {\n        if (StringUtils.isBlank(namespaceId) || StringUtils.isBlank(resourceType)\n            || StringUtils.isBlank(resourceName) || StringUtils.isBlank(version)) {\n            throw new NacosApiException(NacosException.INVALID_PARAM,\n                ErrorCode.PARAMETER_MISSING,\n                \"Required ARD artifact parameter not present\");\n        }\n        if (AiResourceConstants.RESOURCE_TYPE_SKILL.equals(resourceType)) {\n            return skillArtifact(namespaceId, resourceName, version);\n        }\n        if (AiResourceConstants.RESOURCE_TYPE_PROMPT.equals(resourceType)) {\n            return promptArtifact(namespaceId, resourceType, resourceName, version);\n        }\n        if (AiResourceConstants.RESOURCE_TYPE_MCP.equals(resourceType)) {\n            McpServerDetailInfo detail = mcpServerOperationService.getMcpServerDetail(namespaceId,\n                resourceName, mcpName, version);\n            return new ArdArtifact(ArdProtocolConstants.MEDIA_TYPE_MCP, detail);\n        }\n        throw new NacosApiException(NacosException.INVALID_PARAM,\n            ErrorCode.PARAMETER_VALIDATE_ERROR,\n            \"Unsupported ARD artifact resourceType: \" + resourceType);\n    }\n    \n    private ArdArtifact skillArtifact(String namespaceId, String resourceName, String version)\n        throws NacosException {\n        SkillQueryResult result =\n            skillClientOperationService.querySkill(namespaceId, resourceName, version, null, null);\n        try {\n            return new ArdArtifact(ArdProtocolConstants.MEDIA_TYPE_SKILL_PACKAGE,\n                SkillUtils.toZipBytes(result.getSkill()));\n        } catch (Exception e) {\n            throw new NacosApiException(NacosException.SERVER_ERROR,\n                ErrorCode.DATA_ACCESS_ERROR, e, \"Failed to create ARD Skill artifact\");\n        }\n    }\n    \n    private ArdArtifact promptArtifact(String namespaceId, String resourceType,","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/ai-registry-adaptor/src/main/java/com/alibaba/nacos/airegistry/service/ard/ArdArtifactService.java#L74-L110","documentation":"Thrown by ArdArtifactService.get() when the requested resourceType is not one of the three supported AI resource kinds. The service only knows how to build artifacts for SKILL, PROMPT, and MCP (checked against AiResourceConstants.RESOURCE_TYPE_SKILL/PROMPT/MCP). Any other value falls through to this PARAMETER_VALIDATE_ERROR with HTTP 400. It is a client-side contract violation, not a server fault.","triggerScenarios":"Calling the ARD artifact endpoint (e.g. GET on a catalog entry artifact URL) with resourceType set to an unrecognized string such as \"agent\", \"tool\", \"workflow\", or a typo like \"skil\" or \"promt\". The value must exactly equal the constant strings \"skill\", \"prompt\", or \"mcp\" (case-sensitive equals).","commonSituations":"A client hard-codes a resourceType that was never supported; an integrator assumes a new ARD resource kind exists before the server implements it; a URL builder passes the catalog entry kind verbatim while the server expects the lower-level resourceType token; enum/casing mismatch between client and server.","solutions":["Set resourceType to exactly one of \"skill\", \"prompt\", or \"mcp\".","If you are building the URL from a catalog entry, map the entry kind to the supported resourceType token before calling get().","If you genuinely need a new resource kind, extend ArdArtifactService.get() with a new branch and the corresponding AiResourceConstants constant.","Add a client-side guard that rejects unsupported resourceType before the remote call."],"exampleFix":"// before\nString type = \"agent\";\nardArtifactService.get(ns, type, name, version, mcpName);\n\n// after\nString type = \"mcp\"; // must be skill | prompt | mcp\nardArtifactService.get(ns, type, name, version, mcpName);","handlingStrategy":"validation","validationCode":"private static final Set<String> ARD_ARTIFACT_TYPES =\n    Set.of(\"skill\", \"prompt\", \"mcp\");\n\npublic void assertSupportedArtifactType(String resourceType) {\n    if (!ARD_ARTIFACT_TYPES.contains(resourceType)) {\n        throw new IllegalArgumentException(\n            \"resourceType must be one of \" + ARD_ARTIFACT_TYPES + \", got: \" + resourceType);\n    }\n}","typeGuard":"private static final Set<String> SUPPORTED_ARD_TYPES =\n    Set.of(\"skill\", \"prompt\", \"mcp\");\n\nboolean isSupportedArtifactType(String t) {\n    return t != null && SUPPORTED_ARD_TYPES.contains(t);\n}","tryCatchPattern":null,"preventionTips":["Maintain a shared constant set of supported resourceType values and validate against it on the client.","When building artifact URLs from catalog entries, map the entry kind to the canonical resourceType token.","Write an integration test asserting each supported type resolves and unsupported types return 400."],"tags":["ard","ai-registry","parameter-validation","resource-type"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}