{"record":{"id":"60b89f32cfedba76","repo":"alibaba/spring-ai-alibaba","slug":"failed-to-add-nested-convergence-node-to-queue","errorCode":null,"errorMessage":"Failed to add nested convergence node to queue: ","messagePattern":"Failed to add nested convergence node to queue: ","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/internal/ParallelEdgeProcessor.java","lineNumber":329,"sourceCode":"\t\t\t\t\t\t.collect(Collectors.toSet());\n\n\t\t\t\tif (!parallelTargets.isEmpty()) {\n\t\t\t\t\tString nestedConvergence = findConvergenceNode(parallelTargets);\n\t\t\t\t\tif (nestedConvergence != null) {\n\t\t\t\t\t\t// Update reachability: all sources that reached current also reach nested convergence\n\t\t\t\t\t\tSet<String> nestedSources = reachableFrom.computeIfAbsent(nestedConvergence, k -> new HashSet<>());\n\t\t\t\t\t\tint sizeBefore = nestedSources.size();\n\t\t\t\t\t\tnestedSources.addAll(sources);\n\t\t\t\t\t\tboolean sourcesChanged = nestedSources.size() > sizeBefore;\n\n\t\t\t\t\t\tif (nestedSources.size() == startNodeIds.size()) {\n\t\t\t\t\t\t\treturn nestedConvergence;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Only queue if sources actually changed (prevents infinite loops in cycles)\n\t\t\t\t\t\tif (sourcesChanged && nestedSources.size() < startNodeIds.size()) {\n\t\t\t\t\t\t\tif (!queue.offer(nestedConvergence)) {\n\t\t\t\t\t\t\t\tthrow new IllegalStateException(\"Failed to add nested convergence node to queue: \" + nestedConvergence);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tEdgeValue target = edge.target();\n\t\t\tif (target.id() == null) {\n\t\t\t\t// Conditional edge - skip for now\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tString nextNode = target.id();\n\n\t\t\t// Update reachability: all sources that reached current also reach nextNode\n\t\t\tSet<String> nextSources = reachableFrom.computeIfAbsent(nextNode, k -> new HashSet<>());\n\t\t\tint sizeBefore = nextSources.size();","sourceCodeStart":311,"sourceCodeEnd":347,"githubUrl":"https://github.com/alibaba/spring-ai-alibaba/blob/f82da0b50f35744c13968191be2b1cd2452ef550/spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/internal/ParallelEdgeProcessor.java#L311-L347","documentation":"During convergence-node detection, when a nested convergence point's source set changes, the node is re-queued for another fixpoint iteration. If queue.offer fails (only possible for a capacity-bounded deque), an IllegalStateException with this message is thrown. It is a defensive invariant check, not an expected runtime failure.","triggerScenarios":"queue.offer(nestedConvergence) returns false while re-queueing a nested convergence node whose incoming sources changed during the traversal — practically impossible with an unbounded ArrayDeque.","commonSituations":"Not reachable in normal use; indicates a corrupted artifact or modified internals.","solutions":["Confirm the dependency artifact is an unmodified official release.","Report the graph structure and node ids to the maintainers if reproducible.","Rebuild/redownload spring-ai-alibaba-graph-core to eliminate artifact corruption."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { graph.compile(); } catch (IllegalStateException e) { if (e.getMessage().startsWith(\"Failed to add nested convergence node\")) { /* rebuild dependency / report bug */ } }","preventionTips":["Use official release artifacts only","Pin dependency versions","Report reproducible graphs to maintainers"],"tags":["internal","queue","convergence-analysis","defensive-check"],"backgroundTag":"internal-invariant-violation","analyzedSha":"f82da0b50f35744c13968191be2b1cd2452ef550","analyzedAt":"2026-09-09T15:32:42.421Z","contentChangedAt":"2026-09-09T15:32:42.421Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}