alibaba/nacos · error · IllegalArgumentException
{} must be a JSON object
Error message
{} must be a JSON object What it means
Several nested objects in ai_resource.ext JSON must be JSON objects (Maps). The requireJsonObject helper (line 367) throws this when a value expected to be an object is instead a string, number, array, or null. It guards 'provider', 'extensions', 'versionCatalog', and each 'versionCatalog entry'.
Source
Thrown at ai/src/main/java/com/alibaba/nacos/ai/service/agent/metadata/AgentResourceExtSerializer.java:368
validateStringArray(entry, "protocols");
}
}
private static void validateStringArray(Map<?, ?> object, String field) {
Object value = object.get(field);
if (!(value instanceof List)) {
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);View on GitHub (pinned to 9b989acdf1)
Solutions
- Wrap the value in curly braces to make it a JSON object with the correct sub-fields.
- For 'provider', use {"name":"...","url":"..."} instead of a bare string.
- For 'versionCatalog', use {"onlineVersions":[...]} instead of an array or string.
Example fix
// before
"provider":"Acme"
// after
"provider":{"name":"Acme"} Defensive patterns
Strategy: validation
Validate before calling
private static void ensureJsonObject(Object value, String field) {
if (value != null && !(value instanceof Map)) {
throw new IllegalArgumentException(field + " must be a JSON object");
}
} Type guard
public static boolean isJsonObject(Object value) {
return value instanceof Map;
} Try / catch
try {
AgentResourceExtSerializer.deserialize(json);
} catch (IllegalArgumentException e) {
if (e.getMessage().endsWith("must be a JSON object")) {
// wrap the scalar value in an object or fix the producer
}
throw e;
} Prevention
- Always use JSON objects ({}) for provider, extensions, and versionCatalog.
- Never flatten nested objects into scalar strings.
- Test deserialization of all nested object shapes.
When it happens
Trigger: Deserializing ai_resource.ext where, for example, 'provider' is set to a string "MyOrg" instead of an object {"name":"MyOrg"}, or 'versionCatalog' is an array instead of an object.
Common situations: Flattening nested objects into scalar values by mistake; schema migration that changed provider from a string to an object; hand-editing JSON and forgetting braces.
Related errors
- Missing AgentResourceExt field: versionCatalog
- AgentVersionCatalog onlineVersions must be an array
- {} must be an array
- {} must contain only strings
- {} must be a string
AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14).
Data as JSON: /api/errors/8f05aabfba8a82c5.
Report an issue: GitHub.