alibaba/nacos · error · IllegalArgumentException

AgentResourceExt JSON must not be empty

Error message

AgentResourceExt JSON must not be empty

What it means

validateJsonShape(), the first step of deserialize(), rejects a null or empty input string before any JSON parsing. 'AgentResourceExt JSON must not be empty' means the caller passed null or "" as the ext JSON — there is nothing to parse. (The same message is also raised by validateSingleJsonValue if the JSON stream has no token.)

Source

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

            Map<String, Object> version = new LinkedHashMap<String, Object>();
            version.put("version", entry.getVersion());
            version.put("labels", entry.getLabels());
            version.put("protocols", entry.getProtocols());
            versions.add(version);
        }
        result.put("onlineVersions", versions);
        return result;
    }
    
    private static void putIfPresent(Map<String, Object> target, String field, Object value) {
        if (value != null) {
            target.put(field, value);
        }
    }
    
    private static void validateJsonShape(String json) {
        if (json == null || json.isEmpty()) {
            throw new IllegalArgumentException("AgentResourceExt JSON must not be empty");
        }
        validateSingleJsonValue(json);
        final Map<?, ?> root;
        try {
            root = JacksonUtils.toObj(json, Map.class);
        } catch (NacosDeserializationException e) {
            throw new IllegalArgumentException("Invalid AgentResourceExt", e);
        }
        if (root == null) {
            throw new IllegalArgumentException("AgentResourceExt must be a JSON object");
        }
        rejectUnknownFields(root, ROOT_FIELDS, "AgentResourceExt");
        validateJsonInteger(root, "schemaVersion");
        validateOptionalJsonText(root, "displayName");
        validateOptionalJsonText(root, "iconUrl");
        validateProviderShape(root);
        validateExtensionsShape(root);
        validateCatalogShape(root);

View on GitHub (pinned to 9b989acdf1)

Solutions

  1. If the ext column is legitimately empty, treat it as 'no extension' at the caller rather than calling deserialize("").
  2. For rows with empty ext, re-publish the agent with a well-formed ext payload to populate ai_resource.ext.
  3. Guard the call site: only deserialize when the ext string is non-null and non-empty.

Example fix

// before
AgentResourceExt ext = AgentResourceExtSerializer.deserialize(row.getExt()); // row.getExt() is ""

// after
String raw = row.getExt();
AgentResourceExt ext = (raw == null || raw.isEmpty()) ? null : AgentResourceExtSerializer.deserialize(raw);
Defensive patterns

Strategy: validation

Validate before calling

static AgentResourceExt safeDeserialize(String raw) {
    if (raw == null || raw.isEmpty()) return null; // treat as 'no extension'
    return AgentResourceExtSerializer.deserialize(raw);
}

Type guard

static boolean isNonEmptyJson(String raw) {
    return raw != null && !raw.isEmpty() && !raw.trim().isEmpty();
}

Try / catch

try {
    AgentResourceExtSerializer.deserialize(rawJson);
} catch (IllegalArgumentException e) {
    if ("AgentResourceExt JSON must not be empty".equals(e.getMessage())) {
        // ext column empty: re-publish or skip
        return null;
    }
    throw e;
}

Prevention

When it happens

Trigger: deserialize() called with null/empty ai_resource.ext — e.g. reading an agent row whose ext column is empty/NULL, or an API handler deserializing a missing ext payload.

Common situations: An agent record persisted before the typed-ext feature existed (empty ext column), a DB migration that left ext empty, or a client omitting the ext field on a path that still requires it.

Related errors


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