{"record":{"id":"e8b242193b7d3ebd","repo":"alibaba/nacos","slug":"10000-e8b242","errorCode":"10000","errorMessage":"Required parameter 'agentSpecName' type String is not present","messagePattern":"Required parameter 'agentSpecName' type String is not present","errorType":"validation","errorClass":"NacosApiException","httpStatus":400,"severity":"error","filePath":"ai/src/main/java/com/alibaba/nacos/ai/form/agentspecs/admin/AgentSpecForm.java","lineNumber":48,"sourceCode":" *\n * @author nacos\n */\npublic class AgentSpecForm implements NacosForm {\n    \n    @Serial\n    private static final long serialVersionUID = 1L;\n    \n    private String namespaceId;\n    \n    private String agentSpecName;\n    \n    private String version;\n    \n    @Override\n    public void validate() throws NacosApiException {\n        fillDefaultNamespaceId();\n        if (StringUtils.isEmpty(agentSpecName)) {\n            throw new NacosApiException(NacosException.INVALID_PARAM, ErrorCode.PARAMETER_MISSING,\n                \"Required parameter 'agentSpecName' type String is not present\");\n        }\n    }\n    \n    protected void fillDefaultNamespaceId() {\n        if (StringUtils.isEmpty(namespaceId)) {\n            namespaceId = Constants.AgentSpecs.AGENTSPEC_DEFAULT_NAMESPACE;\n        }\n    }\n    \n    public String getNamespaceId() {\n        return namespaceId;\n    }\n    \n    public void setNamespaceId(String namespaceId) {\n        this.namespaceId = namespaceId;\n    }\n    ","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/ai/src/main/java/com/alibaba/nacos/ai/form/agentspecs/admin/AgentSpecForm.java#L30-L66","documentation":"Thrown by EndpointCanonicalizer.canonicalize when its endpoint argument is null. canonicalize produces a canonical copy (URI parsed, transport validated, priority/weight defaulted, metadata sorted) and requires a non-null Endpoint to begin. This is a programmer/contract error, not a data-format error.","triggerScenarios":"Calling EndpointCanonicalizer.canonicalize(null) directly, or passing a list/stream that contains a null Endpoint which is then canonicalized element-wise.","commonSituations":"A collection containing null endpoints due to a partial deserialization; defensive code that calls canonicalize on a possibly-null reference without a prior null check; stream pipelines that forget filter(Objects::nonNull).","solutions":["Null-check (or filter non-null) before calling canonicalize.","Reject null Endpoints at the deserialization/form-validation boundary.","If null is meaningful in your flow, skip canonicalization for that element rather than passing null."],"exampleFix":"// before\nEndpoint canon = EndpointCanonicalizer.canonicalize(endpoint);\n// after\nif (endpoint == null) {\n    throw new IllegalArgumentException(\"endpoint is required\");\n}\nEndpoint canon = EndpointCanonicalizer.canonicalize(endpoint);","handlingStrategy":"type-guard","validationCode":"if (endpoint == null) {\n    throw new IllegalArgumentException(\"Endpoint must not be null\");\n}\nEndpointCanonicalizer.canonicalize(endpoint);","typeGuard":"static boolean isCanonicalizable(Endpoint e) {\n    return e != null;\n}","tryCatchPattern":"try {\n    Endpoint canon = EndpointCanonicalizer.canonicalize(endpoint);\n} catch (IllegalArgumentException e) {\n    // return 400 / skip null endpoint\n}","preventionTips":["Filter collections with Objects::nonNull before canonicalizing.","Null-check at the deserialization boundary."],"tags":["ai-agent","endpoint","null-check","canonicalization","illegal-argument"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}