alibaba/nacos · error · IllegalArgumentException

Runtime Endpoint binding must be complete

Error message

Runtime Endpoint binding must be complete

What it means

Each RuntimeVersionBinding on a runtime Endpoint must be fully populated: the binding itself, runtimeVersion, and versionRange must all be non-null. This guard in canonicalBindings iterates every binding and rejects incomplete entries, ensuring the revision frame can sort and hash version bindings deterministically.

Source

Thrown at ai/src/main/java/com/alibaba/nacos/ai/service/agent/fingerprint/RuntimeEndpointRevision.java:138

                output.writeBoolean(endpoint.getHealthy());
                writeBindings(output, endpoint.getBindings());
            }
        } catch (IOException e) {
            throw new IllegalStateException("Unable to frame Runtime Endpoint projection", e);
        }
        return buffer.toByteArray();
    }
    
    private static List<RuntimeVersionBinding> canonicalBindings(
        List<RuntimeVersionBinding> bindings) {
        if (bindings == null || bindings.isEmpty()) {
            throw new IllegalArgumentException("Runtime Endpoint bindings must not be empty");
        }
        List<RuntimeVersionBinding> result = new ArrayList<RuntimeVersionBinding>(bindings);
        for (RuntimeVersionBinding binding : result) {
            if (binding == null || binding.getRuntimeVersion() == null
                || binding.getVersionRange() == null) {
                throw new IllegalArgumentException("Runtime Endpoint binding must be complete");
            }
        }
        Collections.sort(result, new Comparator<RuntimeVersionBinding>() {
            
            @Override
            public int compare(RuntimeVersionBinding left, RuntimeVersionBinding right) {
                int comparison = AgentVersionComparator.compare(left.getRuntimeVersion(),
                    right.getRuntimeVersion());
                return comparison == 0
                    ? left.getVersionRange().compareTo(right.getVersionRange()) : comparison;
            }
        });
        return result;
    }
    
    private static void writeBindings(DataOutputStream output,
        List<RuntimeVersionBinding> bindings) throws IOException {
        output.writeInt(bindings.size());

View on GitHub (pinned to 9b989acdf1)

Solutions

  1. Set both binding.setRuntimeVersion(...) and binding.setVersionRange(...) on every binding.
  2. Remove null binding elements from the bindings list before computing the revision.
  3. Ensure the registration payload includes both runtimeVersion and versionRange for every binding.

Example fix

// before — incomplete binding
RuntimeVersionBinding binding = new RuntimeVersionBinding();
binding.setRuntimeVersion("1.0.0");
binding.setVersionRange(null); // missing
endpoint.setBindings(List.of(binding));
RuntimeEndpointRevision.compute(ns, name, proto, endpoints); // throws

// after — complete binding
binding.setVersionRange("[1.0,2.0)");
endpoint.setBindings(List.of(binding));
RuntimeEndpointRevision.compute(ns, name, proto, endpoints);
Defensive patterns

Strategy: validation

Validate before calling

for (RuntimeVersionBinding b : endpoint.getBindings()) {
    if (b == null || b.getRuntimeVersion() == null || b.getVersionRange() == null) {
        throw new IllegalArgumentException("Incomplete binding on endpoint: " + endpoint.getUri());
    }
}

Type guard

boolean allBindingsComplete(List<AgentDiscoveryEndpoint> endpoints) {
    return endpoints.stream().flatMap(e -> e.getBindings().stream()).allMatch(
        b -> b != null && b.getRuntimeVersion() != null && b.getVersionRange() != null);
}

Prevention

When it happens

Trigger: Calling RuntimeEndpointRevision.compute with an endpoint whose bindings list contains a RuntimeVersionBinding where getRuntimeVersion() or getVersionRange() is null, or the binding object itself is null.

Common situations: A runtime agent registers a binding with only runtimeVersion but no versionRange. An adaptor partially maps binding data. JSON deserialization leaves a field null because it was absent in the payload. A null element slips into the bindings list.

Related errors


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