{"record":{"id":"00bc30d06c07b8fd","repo":"alibaba/nacos","slug":"runtime-endpoint-bindings-must-not-be-empty-00bc30","errorCode":null,"errorMessage":"Runtime Endpoint bindings must not be empty","messagePattern":"Runtime Endpoint bindings must not be empty","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"api/src/main/java/com/alibaba/nacos/api/ai/utils/AgentModelValidator.java","lineNumber":565,"sourceCode":"            }\n        }\n    }\n    \n    private static void validateRuntimeEndpointSnapshotItem(RuntimeEndpointSnapshot snapshot,\n        AgentVersion selectedVersion, RuntimeEndpointSnapshotItem item,\n        Set<EndpointNaturalKey> endpointKeys) {\n        requireNonNull(item, \"runtimeEndpointSnapshot item\");\n        validateEndpoint(item.getEndpoint());\n        EndpointNaturalKey endpointKey = EndpointNaturalKey.of(snapshot.getNamespaceId(),\n            snapshot.getAgentName(), snapshot.getProtocol(), item.getEndpoint());\n        if (!endpointKeys.add(endpointKey)) {\n            throw new IllegalArgumentException(\"Duplicate runtime Endpoint: \" + endpointKey);\n        }\n        \n        List<RuntimeVersionBinding> bindings = item.getBindings();\n        requireNonNull(bindings, \"runtimeEndpointSnapshot.bindings\");\n        if (bindings.isEmpty()) {\n            throw new IllegalArgumentException(\"Runtime Endpoint bindings must not be empty\");\n        }\n        Set<String> bindingKeys = new HashSet<String>();\n        for (RuntimeVersionBinding binding : bindings) {\n            validateRuntimeVersionBinding(binding, selectedVersion, bindingKeys);\n        }\n        requireNonNull(item.getState(), \"runtime Endpoint state\");\n        requireNonNull(item.getEnabled(), \"runtime Endpoint enabled\");\n        requireNonNull(item.getHealthy(), \"runtime Endpoint healthy\");\n        validateRuntimeEndpointState(item);\n        validateEpochMillis(item.getLastUpdatedTime(), \"lastUpdatedTime\");\n    }\n    \n    private static void validateRuntimeVersionBinding(RuntimeVersionBinding binding,\n        AgentVersion selectedVersion, Set<String> bindingKeys) {\n        requireNonNull(binding, \"runtime Version binding\");\n        AgentVersion runtimeVersion = AgentVersion.parse(binding.getRuntimeVersion());\n        AgentVersionRange versionRange = AgentVersionRange.parse(binding.getVersionRange());\n        if (!versionRange.getValue().equals(binding.getVersionRange())) {","sourceCodeStart":547,"sourceCodeEnd":583,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/api/src/main/java/com/alibaba/nacos/api/ai/utils/AgentModelValidator.java#L547-L583","documentation":"Thrown by validateRuntimeEndpointSnapshotItem when a RuntimeEndpointSnapshotItem.getBindings() is a non-null but empty list. Every runtime endpoint must declare at least one RuntimeVersionBinding tying the endpoint's address to the Agent version range it can serve; an endpoint with no version binding is meaningless to the discovery layer, so the validator treats emptiness as invalid (a null bindings list would have already failed the requireNonNull check with a different message).","triggerScenarios":"Pushing a RuntimeEndpointSnapshot whose item.bindings is [] (present but empty). Reached through AgentModelValidator.validateRuntimeEndpointSnapshot in the runtime management/RAD push flow.","commonSituations":"Serializing an item from a struct whose bindings were filtered out (e.g. all bindings removed because their version range was invalid) leaving an empty list instead of omitting the field; a builder that initializes bindings = new ArrayList<>() and never adds to it; a partial-update payload that zeroes the bindings array.","solutions":["Populate item.bindings with at least one RuntimeVersionBinding whose runtimeVersion and versionRange are valid and consistent.","If the endpoint genuinely has no version to serve, remove the whole RuntimeEndpointSnapshotItem from snapshot.items instead of leaving it bindingless.","Ensure your snapshot builder does not emit items whose binding list was emptied by an upstream filter."],"exampleFix":"// before\nitem.setBindings(Collections.emptyList()); // rejected\n// after\nRuntimeVersionBinding b = new RuntimeVersionBinding();\nb.setRuntimeVersion(\"1.0.0\");\nb.setVersionRange(\"[1.0.0,2.0.0)\");\nitem.setBindings(List.of(b));","handlingStrategy":"validation","validationCode":"for (RuntimeEndpointSnapshotItem it : snapshot.getItems()) {\n    List<RuntimeVersionBinding> b = it.getBindings();\n    if (b == null || b.isEmpty()) {\n        throw new IllegalStateException(\"item has no bindings: \" + it.getEndpoint());\n    }\n}","typeGuard":"static boolean everyItemHasBindings(List<RuntimeEndpointSnapshotItem> items) {\n    for (RuntimeEndpointSnapshotItem it : items) {\n        List<RuntimeVersionBinding> b = it.getBindings();\n        if (b == null || b.isEmpty()) return false;\n    }\n    return true;\n}","tryCatchPattern":"try {\n    AgentModelValidator.validateRuntimeEndpointSnapshot(snapshot);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().equals(\"Runtime Endpoint bindings must not be empty\")) {\n        // remove the item or add a valid binding\n    } else throw e;\n}","preventionTips":["Never emit a snapshot item whose binding list was emptied by a filter.","If an endpoint serves no version, drop the whole item.","Initialize bindings as non-null and add at least one entry."],"tags":["ai-agent","validation","runtime-snapshot","bindings"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}