{"record":{"id":"b396bbd056c81097","repo":"alibaba/nacos","slug":"agentresourceext-must-not-be-null","errorCode":null,"errorMessage":"AgentResourceExt must not be null","messagePattern":"AgentResourceExt must not be null","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"ai/src/main/java/com/alibaba/nacos/ai/service/agent/metadata/AgentResourceExtSerializer.java","lineNumber":118,"sourceCode":"        validateJsonShape(json);\n        final AgentResourceExt result;\n        try {\n            result = JacksonUtils.toObj(json, AgentResourceExt.class);\n        } catch (NacosDeserializationException e) {\n            throw new IllegalArgumentException(\"Invalid AgentResourceExt\", e);\n        }\n        validate(result);\n        return result;\n    }\n    \n    /**\n     * Validate Agent resource extension data against schema version 1.\n     *\n     * @param resourceExt typed extension object\n     */\n    public static void validate(AgentResourceExt resourceExt) {\n        if (resourceExt == null) {\n            throw new IllegalArgumentException(\"AgentResourceExt must not be null\");\n        }\n        if (!Integer.valueOf(AgentResourceExt.SCHEMA_VERSION)\n            .equals(resourceExt.getSchemaVersion())) {\n            throw new IllegalArgumentException(\"AgentResourceExt schemaVersion must be \"\n                + AgentResourceExt.SCHEMA_VERSION);\n        }\n        validateOptionalCodePointLength(resourceExt.getDisplayName(),\n            MAX_DISPLAY_NAME_LENGTH, \"displayName\");\n        validateOptionalAbsoluteUri(resourceExt.getIconUrl(), \"iconUrl\");\n        validateProvider(resourceExt.getProvider());\n        validateExtensions(resourceExt.getExtensions());\n        validateCatalog(resourceExt.getVersionCatalog());\n    }\n    \n    private static void validateProvider(AgentProvider provider) {\n        if (provider == null) {\n            return;\n        }","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/ai/src/main/java/com/alibaba/nacos/ai/service/agent/metadata/AgentResourceExtSerializer.java#L100-L136","documentation":"validate() (and therefore serialize()) rejects a null AgentResourceExt outright. The serializer is strict: it never silently treats null as an empty extension, because ai_resource.ext must always carry at least schemaVersion and versionCatalog. A null here is a programming contract violation, not a data condition.","triggerScenarios":"AgentPersistenceService.serialize(...) is called with a null ext before persisting (AgentPersistenceService.java:970, 1287), e.g. an agent create/update handler built the AgentResourceExt object but a code path left it null, or a caller passed the result of a method that returned null on a lookup miss straight into serialize.","commonSituations":"New agent API handler that forgets to populate the ext object, a refactor that changed the builder to return null on validation failure upstream, or a test/migration that constructs an Agent record without its ext.","solutions":["Ensure the AgentResourceExt is always constructed before serialize: build it with schemaVersion and a versionCatalog at minimum.","If a null ext is legitimately possible at the call site, guard with an explicit null check that returns/throws a domain-specific error instead of calling serialize(null).","Search callers of AgentResourceExtSerializer.serialize for places that pass a possibly-null expression and fix the data flow upstream."],"exampleFix":"// before\nresult.setExt(AgentResourceExtSerializer.serialize(resourceExt)); // resourceExt may be null\n\n// after\nif (resourceExt == null) {\n    throw new IllegalArgumentException(\"agent resourceExt is required\");\n}\nresult.setExt(AgentResourceExtSerializer.serialize(resourceExt));","handlingStrategy":"validation","validationCode":"java.util.Objects.requireNonNull(resourceExt, \"agent resourceExt must not be null\");\nif (resourceExt.getSchemaVersion() == null || resourceExt.getVersionCatalog() == null) {\n    throw new IllegalArgumentException(\"resourceExt is incomplete\");\n}\nAgentResourceExtSerializer.serialize(resourceExt);","typeGuard":null,"tryCatchPattern":"try {\n    AgentResourceExtSerializer.serialize(resourceExt);\n} catch (IllegalArgumentException e) {\n    if (\"AgentResourceExt must not be null\".equals(e.getMessage())) {\n        throw new AgentExtMissingException();\n    }\n    throw e;\n}","preventionTips":["Construct AgentResourceExt via a builder/factory that always sets schemaVersion and versionCatalog.","Static-analysis: flag any serialize(...) call whose argument can be null.","Unit-test the create/update handler with a null ext to confirm a clean domain error."],"tags":["ai-registry","agent","null-check","validation"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}