alibaba/spring-ai-alibaba · error · IllegalStateException
Shell session is not running
Error message
Shell session is not running
What it means
ShellSession.execute() first checks that the underlying process is non-null and alive; if the shell process has exited or was never started, it throws this IllegalStateException instead of writing to a dead process's stdin. It is the guard that keeps command execution tied to a live shell.
Source
Thrown at spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/tools/ShellSessionManager.java:471
try {
if (!process.waitFor(timeoutMs, TimeUnit.MILLISECONDS)) {
process.destroyForcibly();
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
process.destroyForcibly();
}
try {
stdin.close();
} catch (IOException e) {
log.debug("Failed to close stdin", e);
}
}
synchronized CommandResult execute(String command, long timeoutMs, int maxOutputLines, Long maxOutputBytes) {
if (process == null || !process.isAlive()) {
throw new IllegalStateException("Shell session is not running");
}
String marker = DONE_MARKER_PREFIX + UUID.randomUUID().toString().replace("-", "");
long deadline = System.currentTimeMillis() + timeoutMs;
try {
// Clear output queue
outputQueue.clear();
// Send command
stdin.write(command);
if (!command.endsWith("\n")) {
stdin.write("\n");
}
// Send marker command based on shell type
if (isPowerShell) {
// PowerShell only sets $LASTEXITCODE for native programs and scripts. CaptureView on GitHub (pinned to f82da0b50f)
Solutions
- Catch IllegalStateException and call session.restart() (or manager.initialize()) to obtain a live process before retrying the command.
- Check session/process liveness (isAlive) before each execute() and recover proactively.
- Avoid running commands that can terminate the shell itself; run them detached (e.g. 'nohup ... &' or a subshell) if needed.
- Ensure no concurrent thread calls stop()/cleanup() while other threads are executing commands (synchronize at the application level).
Example fix
// before
CommandResult r = session.execute(cmd, timeout, maxLines, maxBytes); // throws if process died
// after
if (session == null || !session.isAlive()) { session.restart(); }
CommandResult r = session.execute(cmd, timeout, maxLines, maxBytes); Defensive patterns
Strategy: try-catch
Validate before calling
// Liveness check before executing: if (session == null || !session.isAlive()) session.restart();
Type guard
boolean sessionAlive(ShellSession s) { return s != null && s.isAlive(); } Try / catch
try {
result = session.execute(cmd, timeout, maxLines, maxBytes);
} catch (IllegalStateException e) {
if (e.getMessage().contains("not running")) {
session.restart();
result = session.execute(cmd, timeout, maxLines, maxBytes);
}
} Prevention
- Check process liveness before each execute() call.
- Never run commands that can kill the host shell ('exit', 'kill $$', fatal crashes); use subshells or nohup.
- Avoid concurrent stop()/cleanup() while commands may be executing.
- Treat long-idle sessions as suspect — restart proactively before reuse.
When it happens
Trigger: Calling session.execute(command, ...) (directly or via executeCommand/startup commands) after the shell process died (e.g. a previous command called 'exit'), after stop()/restart() tore it down, or on a session object whose process was never started.
Common situations: The executed command itself terminated the shell ('exit', fatal crash, OOM kill); a long idle period where the OS reaped the process; concurrent stop() from another thread; using a stale session reference recovered from a registry after the process died.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Startup command failed:
- Failed to initialize shell session
- Shell session not initialized. Call initialize() before exec
- Shell session not initialized. Cannot restart a session that
- Failed to restart shell session
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/08f3738851c01b6b.
Report an issue: GitHub.