alibaba/nacos · error · IllegalArgumentException

latest label and versionCatalog.latestVersion must match

Error message

latest label and versionCatalog.latestVersion must match

What it means

Thrown by validateVersionInfoCatalogConsistency when versionCatalog.latestVersion is non-null but versionInfo.labels["latest"] is either absent or a different value. The two representations of "latest" (the catalog field and the versionInfo label) must agree exactly. This is the non-null-catalog branch paired with error 489.

Source

Thrown at api/src/main/java/com/alibaba/nacos/api/ai/utils/AgentModelValidator.java:443

            || onlineVersionValues.contains(reviewingVersion)) {
            throw new IllegalArgumentException(
                "editingVersion and reviewingVersion must not identify online Versions");
        }
        for (Map.Entry<String, String> label : versionInfo.getLabels().entrySet()) {
            if (label.getValue().equals(editingVersion)
                || label.getValue().equals(reviewingVersion)) {
                throw new IllegalArgumentException(
                    "Labels must not identify editing or reviewing Versions");
            }
        }
        String latestLabelVersion = versionInfo.getLabels().get("latest");
        if (catalog.getLatestVersion() == null) {
            if (latestLabelVersion != null) {
                throw new IllegalArgumentException(
                    "latest label must be absent when no online Version exists");
            }
        } else if (!catalog.getLatestVersion().equals(latestLabelVersion)) {
            throw new IllegalArgumentException(
                "latest label and versionCatalog.latestVersion must match");
        }
        for (AgentVersionCatalogEntry entry : onlineVersions) {
            for (String label : entry.getLabels()) {
                if (!entry.getVersion().equals(versionInfo.getLabels().get(label))) {
                    throw new IllegalArgumentException(
                        "Version catalog label does not match versionInfo: " + label);
                }
            }
        }
        for (Map.Entry<String, String> label : versionInfo.getLabels().entrySet()) {
            if ("latest".equals(label.getKey())
                || !onlineVersionValues.contains(label.getValue())) {
                continue;
            }
            boolean presentInCatalog = false;
            for (AgentVersionCatalogEntry entry : onlineVersions) {
                if (entry.getVersion().equals(label.getValue())

View on GitHub (pinned to 9b989acdf1)

Solutions

  1. Set versionInfo.labels["latest"] to the exact same string as versionCatalog.latestVersion whenever a latest online Version exists.
  2. Centralize latest-pointer assignment so both fields are written together.
  3. After any publish/unpublish, recompute catalog.latestVersion and mirror it into the label in the same mutation.

Example fix

// before
catalog.setLatestVersion("1.3.0"); versionInfo.getLabels().put("latest", "1.2.0");
// after
String latest = catalog.getLatestVersion();
versionInfo.getLabels().put("latest", latest);
Defensive patterns

Strategy: validation

Validate before calling

static void syncLatestLabel(AgentVersionInfo info, AgentVersionCatalog catalog) {
    if (catalog.getLatestVersion() != null) {
        info.getLabels().put("latest", catalog.getLatestVersion());
    }
}

Type guard

static boolean latestLabelMatches(AgentVersionInfo info, AgentVersionCatalog catalog) {
    String latest = catalog.getLatestVersion();
    return latest == null || latest.equals(info.getLabels().get("latest"));
}

Try / catch

try {
    AgentModelValidator.validateAgent(agent);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("latest label and versionCatalog.latestVersion must match")) {
        agent.getVersionInfo().getLabels().put("latest",
            agent.getVersionCatalog().getLatestVersion());
    }
}

Prevention

When it happens

Trigger: Updating catalog.latestVersion during a publish but not updating labels["latest"], or vice versa; deserializing a payload where the two fields were written by different code paths.

Common situations: A publish operation that sets the catalog latest pointer centrally but expects each client to mirror it into labels; partial updates that touch only one of the two fields.

Related errors


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