{"record":{"id":"8c4cb62139693da1","repo":"alibaba/nacos","slug":"agent-replacement-must-not-be-null","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/AgentOperationService.java","lineNumber":145,"sourceCode":"    public AgentOverview getOverview(String namespaceId, String agentName) throws NacosException {\n        AiResource meta = requireMeta(namespaceId, agentName);\n        resourceManager.ensureReadableOrNotFound(meta, \"Agent not found: \" + agentName);\n        return persistenceService.getAgentOverview(namespaceId, agentName,\n            OVERVIEW_VERSION_PAGE_SIZE);\n    }\n    \n    /**\n     * Replace Agent-level presentation, catalog, and resource-status metadata.\n     *\n     * <p>This operation does not modify Agent Version content, owner, or scope.</p>\n     *\n     * @param replacement complete writable Agent replacement\n     * @return updated Agent\n     * @throws NacosException when the Agent is absent, not writable, or persistence fails\n     */\n    public Agent updateAgent(Agent replacement) throws NacosException {\n        if (replacement == null) {\n            throw new IllegalArgumentException(\"Agent replacement must not be null\");\n        }\n        for (int i = 0; i < AiResourceConstants.MAX_WORKING_VERSION_RETRY; i++) {\n            AiResource current =\n                requireWritableMeta(replacement.getNamespaceId(), replacement.getAgentName());\n            Agent result = persistenceService.tryUpdateAgent(replacement, current);\n            if (result != null) {\n                AiResourceTraceService.logSuccess(RESOURCE_TYPE, replacement.getAgentName(), null,\n                    AiResourceTraceService.OP_UPDATE_RESOURCE,\n                    VisibilityHelper.resolveCurrentIdentity(), VisibilityHelper.resolveClientIp());\n                return result;\n            }\n        }\n        throw conflict(\"Agent metadata changed concurrently: \" + replacement.getAgentName());\n    }\n    \n    /**\n     * Filter and page visible Agent summaries.\n     *","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/ai/src/main/java/com/alibaba/nacos/ai/service/agent/AgentOperationService.java#L127-L163","documentation":"Thrown by AgentOperationService.updateAgent as an IllegalArgumentException when the replacement parameter is null. This is a programming-error guard — the public API contract requires a non-null Agent object. It is not a NacosApiException; it will surface as a 500 or unchecked-exception propagation depending on the controller's exception handler.","triggerScenarios":"Calling updateAgent(null) directly. Passing a variable that was not initialized or was set to null by a failed lookup. Deserialization producing null when the request body was empty.","commonSituations":"Controller receives an empty request body that deserializes to null. Code path where the Agent object is conditionally built and the else branch passes null. Refactoring that accidentally removed the initialization.","solutions":["Add a null check before calling updateAgent and return a 400 Bad Request from the controller.","Ensure the caller always constructs and populates the Agent object before the call.","If deserializing, validate the request body is non-empty and maps to a non-null object."],"exampleFix":"// before\nagentOperationService.updateAgent(null);\n\n// after\nif (replacement == null) {\n    throw new IllegalArgumentException(\"replacement must not be null\");\n}\nagentOperationService.updateAgent(replacement);","handlingStrategy":"type-guard","validationCode":"// Null-check at the controller or caller layer\nif (replacement == null) {\n    throw new IllegalArgumentException(\"Agent replacement must not be null\");\n}\nagentOperationService.updateAgent(replacement);","typeGuard":"public static boolean isValidAgentReplacement(Agent replacement) {\n    return replacement != null\n        && StringUtils.isNotBlank(replacement.getNamespaceId())\n        && StringUtils.isNotBlank(replacement.getAgentName());\n}","tryCatchPattern":"try {\n    agentOperationService.updateAgent(replacement);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"must not be null\")) {\n        return ResponseEntity.badRequest().body(e.getMessage());\n    }\n    throw e;\n}","preventionTips":["Add null checks at the API/controller boundary before calling the service.","Use Bean Validation (@NotNull) on request DTOs to reject null at deserialization.","Initialize Agent objects from builders that enforce required fields."],"tags":["agent","null-check","illegal-argument","update","programming-error"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}