{"record":{"id":"fe7d104f39f51013","repo":"alibaba/nacos","slug":"parameter-validate-error-fe7d10","errorCode":"PARAMETER_VALIDATE_ERROR","errorMessage":"ARD namespaceId should be passed as query parameter","messagePattern":"ARD namespaceId should be passed as query parameter","errorType":"exception","errorClass":"NacosApiException","httpStatus":400,"severity":"error","filePath":"ai-registry-adaptor/src/main/java/com/alibaba/nacos/airegistry/controller/ArdSearchController.java","lineNumber":150,"sourceCode":"        if (request != null) {\n            request.setNamespaceId(resolveNamespaceId(queryNamespaceId, request.getNamespaceId()));\n        }\n    }\n    \n    private void bindNamespaceId(String queryNamespaceId, ArdExploreRequest request)\n        throws NacosApiException {\n        if (request != null) {\n            request.setNamespaceId(resolveNamespaceId(queryNamespaceId, request.getNamespaceId()));\n        }\n    }\n    \n    private String resolveNamespaceId(String queryNamespaceId, String bodyNamespaceId)\n        throws NacosApiException {\n        if (StringUtils.isBlank(queryNamespaceId)) {\n            if (StringUtils.isNotBlank(bodyNamespaceId)\n                && !com.alibaba.nacos.api.common.Constants.DEFAULT_NAMESPACE_ID\n                    .equals(bodyNamespaceId)) {\n                throw new NacosApiException(NacosException.INVALID_PARAM,\n                    ErrorCode.PARAMETER_VALIDATE_ERROR,\n                    \"ARD namespaceId should be passed as query parameter\");\n            }\n            return bodyNamespaceId;\n        }\n        if (StringUtils.isNotBlank(bodyNamespaceId) && !queryNamespaceId.equals(bodyNamespaceId)) {\n            throw new NacosApiException(NacosException.INVALID_PARAM,\n                ErrorCode.PARAMETER_VALIDATE_ERROR,\n                \"ARD query namespaceId should match request body namespaceId\");\n        }\n        return queryNamespaceId;\n    }\n    \n    /**\n     * Return the versioned artifact document behind an ARD catalog entry URL.\n     */\n    @Since(\"3.3.0\")\n    @GetMapping(\"/artifacts\")","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/ai-registry-adaptor/src/main/java/com/alibaba/nacos/airegistry/controller/ArdSearchController.java#L132-L168","documentation":"ARD (Agent Registry Discovery) search/explore endpoints take namespaceId as a query parameter. resolveNamespaceId rejects a request where the query namespaceId is omitted but the request body carries a non-default namespaceId, throwing PARAMETER_VALIDATE_ERROR (HTTP 400). Only the default namespace (Constants.DEFAULT_NAMESPACE_ID) may be conveyed via the body when the query param is absent.","triggerScenarios":"POST to /search or /explore with no ?namespaceId= query parameter, but a JSON body whose namespaceId field is set to a custom (non-default) namespace.","commonSituations":"An SDK that defaults namespaceId in the body; migrating from an API that accepted body namespaceId; forgetting to append the query param while the body still carries a tenant namespace.","solutions":["Pass the namespace as a query parameter: ?namespaceId=<your-namespace>.","Or remove namespaceId from the body to target the default namespace.","Keep namespaceId in exactly one place (the query string) in your client."],"exampleFix":"// before\nPOST /search  body {\"namespaceId\":\"tenant-a\", ...}\n\n// after\nPOST /search?namespaceId=tenant-a  body {...}","handlingStrategy":"validation","validationCode":"// Put namespaceId in the query string, not (only) the body\nString ns = StringUtils.isBlank(bodyNs) ? Constants.DEFAULT_NAMESPACE_ID : bodyNs;\nURI uri = UriComponentsBuilder.fromHttpUrl(baseUrl + \"/search\")\n        .queryParam(\"namespaceId\", ns)\n        .build().toUri();\nrequest.setNamespaceId(null); // do not rely on body for non-default namespaces","typeGuard":null,"tryCatchPattern":"try {\n    ardClient.search(queryNs, request);\n} catch (NacosApiException e) {\n    if (e.getMessage().contains(\"passed as query parameter\")) {\n        // move namespaceId from body to the query string and retry once\n        queryNs = request.getNamespaceId();\n        request.setNamespaceId(null);\n        return ardClient.search(queryNs, request);\n    }\n    throw e;\n}","preventionTips":["Standardize on the query string for namespaceId in ARD clients.","Strip namespaceId from request bodies to avoid ambiguity.","Document the convention in your client wrapper."],"tags":["ard","namespace","validation","ai"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}