alibaba/spring-ai-alibaba · warning · RuntimeException
Interrupted while waiting for execution slot
Error message
Interrupted while waiting for execution slot
What it means
evalNodeActionWithSemaphore waits on a Semaphore to acquire an execution slot before running a parallel branch. If the waiting thread is interrupted, it restores the interrupt flag, logs, and throws RuntimeException("Interrupted while waiting for execution slot", e). This preserves cancellation semantics while converting the checked InterruptedException into an unchecked one for the CompletableFuture pipeline.
Source
Thrown at spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/internal/node/ParallelNode.java:426
actualNodeId, semaphore.availablePermits());
semaphore.acquire();
logger.debug("Node {} acquired semaphore permit. Remaining permits: {}",
actualNodeId, semaphore.availablePermits());
try {
logger.debug("Executing task for node {} in thread {} with concurrency control",
actualNodeId, Thread.currentThread().getName());
return evalNodeActionSync(action, actualNodeId, state, config).join();
} finally {
// Always release the semaphore permit
semaphore.release();
logger.debug("Node {} released semaphore permit. Available permits: {}",
actualNodeId, semaphore.availablePermits());
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
logger.error("Node {} was interrupted while waiting for semaphore", actualNodeId, e);
throw new RuntimeException("Interrupted while waiting for execution slot", e);
} catch (Exception e) {
logger.error("Error executing task for node {}", actualNodeId, e);
throw new RuntimeException(e);
}
}, executor);
}
@Override
public CompletableFuture<Map<String, Object>> apply(OverAllState state, RunnableConfig config) {
// Get maxConcurrency from config metadata
Integer maxConcurrency = config.metadata(formatMaxConcurrencyKey(nodeId))
.filter(value -> value instanceof Integer)
.map(Integer.class::cast)
.orElse(null);
// Create semaphore for concurrency control if maxConcurrency is set
Semaphore semaphore = maxConcurrency != null ? new Semaphore(maxConcurrency) : null;
View on GitHub (pinned to f82da0b50f)
Solutions
- Check whether your application or framework intentionally cancelled the execution and handle cancellation gracefully
- Avoid interrupting executor threads; use cancellation-aware timeouts instead
- Increase semaphore permits if waits are long and timeouts are triggering cancellation
- Catch the exception in the caller and treat it as cancellation, not a code bug
Example fix
// before
future.get(30, TimeUnit.SECONDS); // cancels & interrupts branches on timeout
// after
try {
future.get(30, TimeUnit.SECONDS);
} catch (ExecutionException e) {
if (e.getCause() instanceof RuntimeException re && "Interrupted while waiting for execution slot".equals(re.getMessage())) {
logger.info("parallel branch cancelled by timeout");
}
} Defensive patterns
Strategy: try-catch
Try / catch
try {
node.apply(state, config).join();
} catch (CompletionException e) {
if (e.getCause() instanceof RuntimeException re
&& re.getCause() instanceof InterruptedException) {
// treat as cancellation, not failure
}
} Prevention
- Design cancellation handling before cancelling graph futures
- Avoid aggressive timeout+cancel patterns around parallel nodes
- Size the semaphore generously so waits are short
- Shut down executors only after all graph runs complete
When it happens
Trigger: Thread interrupt delivered while blocked in semaphore.acquire() — typically when the enclosing CompletableFuture is cancelled, the overall graph run is cancelled/times out, or the JVM/shutdown hooks interrupt worker threads.
Common situations: Cancelling a graph execution from another thread; application shutdown during a long-running parallel node; timeout wrappers that cancel futures and interrupt executors.
Understand the failure class
Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.
Related errors
- WORKFLOW_RUN_CANCEL
- Retry interrupted
- Tool execution was cancelled
- Tool execution was cancelled
- Failed to create subgraph action for path starting at:
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/ac7c32d194d3de6a.
Report an issue: GitHub.