alibaba/nacos · error · IllegalArgumentException
{} must contain only strings
Error message
{} must contain only strings What it means
Inside each versionCatalog.onlineVersions entry, every element of the 'labels' and 'protocols' arrays must be a JSON string. The validateStringArray helper (line 360) throws this when an array element is a number, boolean, object, or null. This ensures the catalog only stores string-tagged data.
Source
Thrown at ai/src/main/java/com/alibaba/nacos/ai/service/agent/metadata/AgentResourceExtSerializer.java:361
"AgentVersionCatalog onlineVersions must be an array");
}
for (Object entryValue : (List<?>) versionsValue) {
Map<?, ?> entry = requireJsonObject(entryValue, "versionCatalog entry");
rejectUnknownFields(entry, CATALOG_ENTRY_FIELDS, "AgentVersionCatalogEntry");
validateRequiredJsonText(entry, "version");
validateStringArray(entry, "labels");
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) {View on GitHub (pinned to 9b989acdf1)
Solutions
- Convert every element in the labels/protocols arrays to a quoted JSON string.
- Audit the producer code that builds these arrays to ensure only String values are added.
- Use AgentResourceExtSerializer.deserialize() in integration tests to catch type mismatches early.
Example fix
// before
{"version":"1.0.0","protocols":["a2a",42]}
// after
{"version":"1.0.0","protocols":["a2a","42"]} Defensive patterns
Strategy: validation
Validate before calling
private static void ensureAllStrings(List<?> list, String field) {
for (Object item : list) {
if (!(item instanceof String)) {
throw new IllegalArgumentException(field + " contains non-string: " + item);
}
}
} Type guard
public static boolean isStringArray(List<?> list) {
if (list == null) return false;
for (Object item : list) {
if (!(item instanceof String)) return false;
}
return true;
} Try / catch
try {
AgentResourceExtSerializer.deserialize(json);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("must contain only strings")) {
// sanitize the array: convert all elements to strings
}
throw e;
} Prevention
- Ensure producer code only adds String values to labels and protocols lists.
- Use typed List<String> in DTOs so the compiler catches mixed-type additions.
- Validate JSON payloads with a schema that specifies items: {type: string}.
When it happens
Trigger: Deserializing ai_resource.ext where a catalog entry's 'labels' or 'protocols' array contains a non-string element, e.g. [123] or [true] or [{"key":"val"}].
Common situations: Numeric protocol codes or boolean flags mistakenly placed in the protocols/labels arrays; automated JSON generators that emit unquoted values; schema confusion with metadata maps that allow mixed types.
Related errors
- Missing AgentResourceExt field: versionCatalog
- AgentVersionCatalog onlineVersions must be an array
- {} must be an array
- {} must be a JSON object
- {} must be a string
AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14).
Data as JSON: /api/errors/e86856a7903cff2f.
Report an issue: GitHub.