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

  1. Check whether your application or framework intentionally cancelled the execution and handle cancellation gracefully
  2. Avoid interrupting executor threads; use cancellation-aware timeouts instead
  3. Increase semaphore permits if waits are long and timeouts are triggering cancellation
  4. 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

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


AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09). Data as JSON: /api/errors/ac7c32d194d3de6a. Report an issue: GitHub.