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
- 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)'.
- If the endpoint serves exactly one version, set versionRange to the canonical exact form '[<runtimeVersion>]'.
- Re-derive versionRange from runtimeVersion programmatically rather than maintaining the two fields by hand.
- 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
- Keep runtimeVersion and versionRange derived from one source.
- For single-version endpoints use versionRange = '[' + runtimeVersion + ']'.
- Re-validate when bumping the deployed runtimeVersion.
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
- Snapshot binding does not match selected Version: {selectedV
- Runtime Endpoint bindings must not be empty
- Runtime Version range must be canonical
- Duplicate Runtime Version binding
- Duplicate runtime Endpoint: {endpointKey}
AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14).
Data as JSON: /api/errors/52c10d41d50e2686.
Report an issue: GitHub.