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

  1. Wrap the value in curly braces to make it a JSON object with the correct sub-fields.
  2. For 'provider', use {"name":"...","url":"..."} instead of a bare string.
  3. 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

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


AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14). Data as JSON: /api/errors/8f05aabfba8a82c5. Report an issue: GitHub.