{"record":{"id":"836d859cd56dc158","repo":"alibaba/nacos","slug":"must-be-a-string","errorCode":null,"errorMessage":"{} must be a string","messagePattern":"(.+?) must be a string","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"ai/src/main/java/com/alibaba/nacos/ai/service/agent/metadata/AgentResourceExtSerializer.java","lineNumber":375,"sourceCode":"            throw new IllegalArgumentException(field + \" must be an array\");\n        }\n        for (Object item : (List<?>) value) {\n            if (!(item instanceof String)) {\n                throw new IllegalArgumentException(field + \" must contain only strings\");\n            }\n        }\n    }\n    \n    private static Map<?, ?> requireJsonObject(Object value, String fieldName) {\n        if (!(value instanceof Map)) {\n            throw new IllegalArgumentException(fieldName + \" must be a JSON object\");\n        }\n        return (Map<?, ?>) value;\n    }\n    \n    private static void validateRequiredJsonText(Map<?, ?> object, String field) {\n        if (!(object.get(field) instanceof String)) {\n            throw new IllegalArgumentException(field + \" must be a string\");\n        }\n    }\n    \n    private static void validateOptionalJsonText(Map<?, ?> object, String field) {\n        if (object.containsKey(field) && !(object.get(field) instanceof String)) {\n            throw new IllegalArgumentException(field + \" must be a string\");\n        }\n    }\n    \n    private static void validateJsonInteger(Map<?, ?> object, String field) {\n        Object value = object.get(field);\n        if (!(value instanceof Byte || value instanceof Short || value instanceof Integer\n            || value instanceof Long)) {\n            throw new IllegalArgumentException(field + \" must be an integer\");\n        }\n    }\n    \n    private static void rejectUnknownFields(Map<?, ?> object, Set<String> allowedFields,","sourceCodeStart":357,"sourceCodeEnd":393,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/ai/src/main/java/com/alibaba/nacos/ai/service/agent/metadata/AgentResourceExtSerializer.java#L357-L393","documentation":"Certain fields in ai_resource.ext JSON are required and must be strings. The validateRequiredJsonText helper (line 374) throws this when a mandatory string field is missing entirely or is present but not a string. It guards 'provider.name' and each catalog entry's 'version' field.","triggerScenarios":"Deserializing ai_resource.ext where provider is present but has no 'name' field, or where a catalog entry omits 'version' or sets it to a non-string type.","commonSituations":"Omitting the provider name when the provider object is otherwise populated; catalog entries built from version objects that forgot to set the version string; numeric version identifiers not quoted as strings.","solutions":["Ensure the field is present and is a quoted JSON string.","For provider, always include \"name\":\"...\" inside the provider object.","For catalog entries, always include \"version\":\"1.0.0\" as a string."],"exampleFix":"// before\n\"provider\":{\"url\":\"https://acme.com\"}\n// after\n\"provider\":{\"name\":\"Acme\",\"url\":\"https://acme.com\"}","handlingStrategy":"validation","validationCode":"private static void ensureRequiredString(Map<?,?> obj, String field) {\n    if (!(obj.get(field) instanceof String)) {\n        throw new IllegalArgumentException(field + \" is required and must be a string\");\n    }\n}","typeGuard":"public static boolean hasRequiredString(Map<?,?> obj, String field) {\n    return obj != null && obj.get(field) instanceof String;\n}","tryCatchPattern":"try {\n    AgentResourceExtSerializer.deserialize(json);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().endsWith(\"must be a string\") && e.getMessage().contains(\"version\")) {\n        // add the missing version field as a quoted string\n    }\n    throw e;\n}","preventionTips":["Always include provider.name and catalog entry version as quoted strings.","Use typed DTOs with String fields annotated @NotNull for required fields.","Validate required string fields before serialization."],"tags":["validation","ai-agent","json-schema","serialization"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}