{"record":{"id":"2f2b19559b18645c","repo":"alibaba/nacos","slug":"agent-replacement-must-not-be-null-2f2b19","errorCode":null,"errorMessage":"Agent replacement must not be null","messagePattern":"Agent replacement must not be null","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":400,"severity":"error","filePath":"ai/src/main/java/com/alibaba/nacos/ai/service/agent/AgentPersistenceService.java","lineNumber":1083,"sourceCode":"            throw new IllegalArgumentException(\"Agent Version agentName does not match request\");\n        }\n        if (version.getStatus() != null\n            && !AiConstants.Agent.VERSION_STATUS_ONLINE.equals(version.getStatus())) {\n            throw new IllegalArgumentException(\"Agent Version status must be online\");\n        }\n        if (version.getContentDigest() != null || version.getCreateTime() != null\n            || version.getUpdateTime() != null) {\n            throw new IllegalArgumentException(\n                \"Agent Version must not contain read-only projection fields\");\n        }\n        if (preferredLatest != null && !version.getVersion().equals(preferredLatest)) {\n            throw new IllegalArgumentException(\"preferredLatest must target the created Version\");\n        }\n    }\n    \n    private void validateAgentUpdateInputs(Agent replacement) {\n        if (replacement == null) {\n            throw new IllegalArgumentException(\"Agent replacement must not be null\");\n        }\n        AgentValidationUtils.validateNamespaceId(replacement.getNamespaceId());\n        AgentValidationUtils.validateAgentName(replacement.getAgentName());\n        if (replacement.getVersionInfo() != null || replacement.getVersionCatalog() != null\n            || replacement.getMetaVersion() != null || replacement.getCreateTime() != null\n            || replacement.getUpdateTime() != null) {\n            throw new IllegalArgumentException(\n                \"Agent update input must not contain read-only projection fields\");\n        }\n    }\n    \n    private Agent normalizeAgentUpdate(Agent source, Agent current) {\n        Agent result = new Agent();\n        result.setNamespaceId(source.getNamespaceId());\n        result.setAgentName(source.getAgentName());\n        result.setDisplayName(source.getDisplayName());\n        result.setDescription(source.getDescription());\n        result.setIconUrl(source.getIconUrl());","sourceCodeStart":1065,"sourceCodeEnd":1101,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/ai/src/main/java/com/alibaba/nacos/ai/service/agent/AgentPersistenceService.java#L1065-L1101","documentation":"The tryUpdateAgent method requires a non-null Agent replacement object containing the writable fields for a CAS (compare-and-set) metadata update. A null replacement means the caller has no data to write, which is a programming error.","triggerScenarios":"Calling AgentPersistenceService.tryUpdateAgent(null, current) or the Agent update flow (PUT /v3/admin/ai/agent) with a null Agent body. The application service that reloads and authorizes the Resource before each retry passes the replacement down; a null reaches this method when upstream request binding fails to produce an Agent object.","commonSituations":"The HTTP PUT request body is empty or malformed so Spring binding yields null. An internal retry loop passes null when the previous attempt produced no replacement. A code path calls tryUpdateAgent before validating the request object.","solutions":["Ensure the Agent replacement object is constructed and populated before calling tryUpdateAgent.","Validate non-null at the controller/service boundary before delegating to tryUpdateAgent.","Check the HTTP request body is valid JSON with the expected Agent fields."],"exampleFix":"// before\npersistenceService.tryUpdateAgent(null, current); // throws\n\n// after\nAgent replacement = new Agent();\nreplacement.setNamespaceId(\"public\");\nreplacement.setAgentName(\"my-agent\");\nreplacement.setDisplayName(\"Updated Name\");\npersistenceService.tryUpdateAgent(replacement, current);","handlingStrategy":"validation","validationCode":"if (replacement == null) {\n    throw new IllegalArgumentException(\"Agent replacement must not be null\");\n}","typeGuard":"boolean isUpdateableAgent(Agent a) {\n    return a != null && a.getNamespaceId() != null && a.getAgentName() != null;\n}","tryCatchPattern":null,"preventionTips":["Validate the request body is non-null at the controller layer before calling the service.","Use @RequestBody(required = true) or equivalent binding to reject empty bodies early."],"tags":["agent","ai-registry","validation","agent-update","null-check"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}