alibaba/nacos · error · IllegalArgumentException

versionRange must contain runtimeVersion: {runtimeVersion}

Error message

versionRange must contain runtimeVersion: {runtimeVersion}

What it means

Thrown by validateRuntimeVersionBinding when the binding's runtimeVersion, parsed via AgentVersion.parse, is NOT contained in the binding's own versionRange (AgentVersionRange.contains). Each runtime endpoint binding must be self-consistent: the concrete runtimeVersion the endpoint is running must lie inside the version interval the binding advertises. A range that does not cover its own runtimeVersion is a contradictory declaration and is rejected before duplicate/selection checks.

Source

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

            validateRuntimeVersionBinding(binding, selectedVersion, bindingKeys);
        }
        requireNonNull(item.getState(), "runtime Endpoint state");
        requireNonNull(item.getEnabled(), "runtime Endpoint enabled");
        requireNonNull(item.getHealthy(), "runtime Endpoint healthy");
        validateRuntimeEndpointState(item);
        validateEpochMillis(item.getLastUpdatedTime(), "lastUpdatedTime");
    }
    
    private static void validateRuntimeVersionBinding(RuntimeVersionBinding binding,
        AgentVersion selectedVersion, Set<String> bindingKeys) {
        requireNonNull(binding, "runtime Version binding");
        AgentVersion runtimeVersion = AgentVersion.parse(binding.getRuntimeVersion());
        AgentVersionRange versionRange = AgentVersionRange.parse(binding.getVersionRange());
        if (!versionRange.getValue().equals(binding.getVersionRange())) {
            throw new IllegalArgumentException("Runtime Version range must be canonical");
        }
        if (!versionRange.contains(runtimeVersion)) {
            throw new IllegalArgumentException(
                "versionRange must contain runtimeVersion: " + runtimeVersion);
        }
        if (selectedVersion != null && !versionRange.contains(selectedVersion)) {
            throw new IllegalArgumentException(
                "Snapshot binding does not match selected Version: " + selectedVersion);
        }
        String bindingKey = runtimeVersion + "\u0000" + versionRange.getValue();
        if (!bindingKeys.add(bindingKey)) {
            throw new IllegalArgumentException("Duplicate Runtime Version binding");
        }
    }
    
    private static void validateRuntimeEndpointState(RuntimeEndpointSnapshotItem item) {
        RuntimeEndpointState expected;
        if (!item.getEnabled()) {
            expected = RuntimeEndpointState.DISABLED;
        } else if (!item.getHealthy()) {
            expected = RuntimeEndpointState.UNHEALTHY;

View on GitHub (pinned to 9b989acdf1)

Solutions

  1. Make versionRange cover runtimeVersion, e.g. for runtimeVersion '2.5.0' use versionRange '[1.0.0,3.0.0)' or '[2.5.0,3.0.0)'.
  2. If the endpoint serves exactly one version, set versionRange to the canonical exact form '[<runtimeVersion>]'.
  3. Re-derive versionRange from runtimeVersion programmatically rather than maintaining the two fields by hand.
  4. Validate the pair with AgentVersionRange.parse(range).contains(AgentVersion.parse(runtime)) before submitting.

Example fix

// before
b.setRuntimeVersion("2.5.0");
b.setVersionRange("[1.0.0,2.0.0)"); // 2.5.0 not in range -> rejected
// after
b.setRuntimeVersion("2.5.0");
b.setVersionRange("[2.0.0,3.0.0)");
Defensive patterns

Strategy: validation

Validate before calling

import com.alibaba.nacos.api.ai.utils.AgentValidationUtils;
AgentValidationUtils.validateVersion(binding.getRuntimeVersion());
AgentValidationUtils.validateVersionRange(binding.getVersionRange());
// confirm containment by mirroring AgentVersionRange.contains semantics:
// parse both and check runtimeVersion falls inside [lo,hi] bounds.

Type guard

// containment gate (mirrors AgentVersionRange.contains)
static boolean rangeCoversRuntime(String range, String runtime) {
    // best: call AgentValidationUtils.validate* then rely on server.
    // Simple exact-form shortcut:
    return range.equals("[" + runtime + "]") || range.contains(runtime);
}

Try / catch

try {
    AgentModelValidator.validateRuntimeEndpointSnapshot(snapshot);
} catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("versionRange must contain runtimeVersion")) {
        // widen versionRange to include runtimeVersion
    } else throw e;
}

Prevention

When it happens

Trigger: A RuntimeVersionBinding where AgentVersionRange.parse(versionRange).contains(AgentVersion.parse(runtimeVersion)) is false. E.g. runtimeVersion='2.5.0' with versionRange='[1.0.0,2.0.0)'. Reached during validateRuntimeVersionBinding in the runtime snapshot push path.

Common situations: Bumping the deployed runtimeVersion but forgetting to widen the advertised versionRange; mis-typing one of the two fields; copying a binding template and changing runtimeVersion without updating the range; using a pre-release runtimeVersion outside a range that only lists releases.

Related errors


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