alibaba/nacos · error · IllegalArgumentException
{} must be a string
Error message
{} must be a string What it means
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.
Source
Thrown at ai/src/main/java/com/alibaba/nacos/ai/service/agent/metadata/AgentResourceExtSerializer.java:375
throw new IllegalArgumentException(field + " must be an array");
}
for (Object item : (List<?>) value) {
if (!(item instanceof String)) {
throw new IllegalArgumentException(field + " must contain only strings");
}
}
}
private static Map<?, ?> requireJsonObject(Object value, String fieldName) {
if (!(value instanceof Map)) {
throw new IllegalArgumentException(fieldName + " must be a JSON object");
}
return (Map<?, ?>) value;
}
private static void validateRequiredJsonText(Map<?, ?> object, String field) {
if (!(object.get(field) instanceof String)) {
throw new IllegalArgumentException(field + " must be a string");
}
}
private static void validateOptionalJsonText(Map<?, ?> object, String field) {
if (object.containsKey(field) && !(object.get(field) instanceof String)) {
throw new IllegalArgumentException(field + " must be a string");
}
}
private static void validateJsonInteger(Map<?, ?> object, String field) {
Object value = object.get(field);
if (!(value instanceof Byte || value instanceof Short || value instanceof Integer
|| value instanceof Long)) {
throw new IllegalArgumentException(field + " must be an integer");
}
}
private static void rejectUnknownFields(Map<?, ?> object, Set<String> allowedFields,View on GitHub (pinned to 9b989acdf1)
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.
Example fix
// before
"provider":{"url":"https://acme.com"}
// after
"provider":{"name":"Acme","url":"https://acme.com"} Defensive patterns
Strategy: validation
Validate before calling
private static void ensureRequiredString(Map<?,?> obj, String field) {
if (!(obj.get(field) instanceof String)) {
throw new IllegalArgumentException(field + " is required and must be a string");
}
} Type guard
public static boolean hasRequiredString(Map<?,?> obj, String field) {
return obj != null && obj.get(field) instanceof String;
} Try / catch
try {
AgentResourceExtSerializer.deserialize(json);
} catch (IllegalArgumentException e) {
if (e.getMessage().endsWith("must be a string") && e.getMessage().contains("version")) {
// add the missing version field as a quoted string
}
throw e;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Missing AgentResourceExt field: versionCatalog
- AgentVersionCatalog onlineVersions must be an array
- {} must be an array
- {} must contain only strings
- {} must be a JSON object
AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14).
Data as JSON: /api/errors/836d859cd56dc158.
Report an issue: GitHub.