alibaba/nacos · error · IllegalArgumentException

{} is not a JSON value

Error message

{} is not a JSON value

What it means

validateJsonValue() is the terminal fallback: any extension value that is not null, String, Boolean, a finite Number, List, or Map throws '<fieldName> is not a JSON value'. This rejects arbitrary Java objects that have no direct JSON representation (custom POJOs, dates, enums-as-objects, arrays of non-JSON types not wrapped in List).

Source

Thrown at ai/src/main/java/com/alibaba/nacos/ai/service/agent/metadata/AgentResourceExtSerializer.java:208

            return;
        }
        if (value instanceof List) {
            for (Object item : (List<?>) value) {
                validateJsonValue(item, fieldName);
            }
            return;
        }
        if (value instanceof Map) {
            for (Map.Entry<?, ?> entry : ((Map<?, ?>) value).entrySet()) {
                if (!(entry.getKey() instanceof String)) {
                    throw new IllegalArgumentException(
                        fieldName + " contains a non-string JSON object key");
                }
                validateJsonValue(entry.getValue(), fieldName);
            }
            return;
        }
        throw new IllegalArgumentException(fieldName + " is not a JSON value");
    }
    
    private static void validateCatalog(AgentVersionCatalog catalog) {
        AgentModelValidator.validateVersionCatalog(catalog);
        List<AgentVersionCatalogEntry> versions = catalog.getOnlineVersions();
        for (int i = 1; i < versions.size(); i++) {
            String previous = versions.get(i - 1).getVersion();
            String current = versions.get(i).getVersion();
            if (AgentVersionComparator.compare(previous, current) <= 0) {
                throw new IllegalArgumentException(
                    "Agent Version catalog must use descending Version order");
            }
        }
    }
    
    private static void validateOptionalAbsoluteUri(String value, String fieldName) {
        if (value == null) {
            return;

View on GitHub (pinned to 9b989acdf1)

Solutions

  1. Convert non-JSON values to a supported type first: UUID -> toString, Date/Instant -> ISO string, enum -> name(), int[] -> List<Integer>.
  2. If you need a structured value, build a Map<String,Object> or List<Object>.
  3. Add a pre-flight validator in tests that walks extensions and asserts each leaf is one of the allowed types.

Example fix

// before
ext.put("id", java.util.UUID.randomUUID()); // not a JSON value
ext.put("ports", new int[]{8080, 8081}); // primitive array, not a List

// after
ext.put("id", java.util.UUID.randomUUID().toString());
ext.put("ports", java.util.List.of(8080, 8081));
Defensive patterns

Strategy: type-guard

Validate before calling

static boolean isJsonValue(Object v) {
    if (v == null || v instanceof String || v instanceof Boolean || v instanceof Number
            || v instanceof List || v instanceof Map) {
        if (v instanceof Float) return Float.isFinite((Float) v);
        if (v instanceof Double) return Double.isFinite((Double) v);
        return true;
    }
    return false;
}

Type guard

static boolean isJsonCompatible(Object v) {
    if (v == null) return true;
    if (v instanceof String || v instanceof Boolean) return true;
    if (v instanceof Float) return Float.isFinite((Float) v);
    if (v instanceof Double) return Double.isFinite((Double) v);
    if (v instanceof Byte || v instanceof Short || v instanceof Integer || v instanceof Long) return true;
    if (v instanceof List) return ((List<?>) v).stream().allMatch(AgentExtGuards::isJsonCompatible);
    if (v instanceof Map) return ((Map<?,?>) v).keySet().stream().allMatch(k -> k instanceof String)
            && ((Map<?,?>) v).values().stream().allMatch(AgentExtGuards::isJsonCompatible);
    return false;
}

Prevention

When it happens

Trigger: An extensions value is a Java object whose runtime type is none of the allowed categories — e.g. a UUID, an enum constant, a java.util.Date, a typed POJO, or a primitive array (int[]).

Common situations: Storing domain objects directly into extensions instead of converting to a JSON-compatible structure; using primitive arrays instead of List.

Related errors


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