alibaba/spring-ai-alibaba · error · RuntimeException
Failed to restart shell session
Error message
Failed to restart shell session
What it means
ShellSession.restart() stops the underlying OS process (waiting up to terminationTimeout) and then calls start() to spawn a fresh shell process. If start() throws an IOException (process cannot be spawned), restart() wraps it in this RuntimeException. Callers like restartSession() and collectOutput() hit this when the shell cannot be relaunched.
Source
Thrown at spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/tools/ShellSessionManager.java:436
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getErrorStream()))) {
String line;
while ((line = reader.readLine()) != null) {
outputQueue.offer(new OutputLine("stderr", line));
}
} catch (IOException e) {
log.debug("Stderr reader terminated", e);
} finally {
outputQueue.offer(new OutputLine("stderr", null)); // EOF marker
}
}, "shell-stderr-reader").start();
}
void restart() {
stop(this.terminationTimeout);
try {
start();
} catch (IOException e) {
throw new RuntimeException("Failed to restart shell session", e);
}
}
void stop(long timeoutMs) {
if (process == null || !process.isAlive()) {
return;
}
terminated = true;
try {
stdin.write("exit\n");
stdin.flush();
} catch (IOException e) {
log.debug("Failed to send exit command", e);
}
try {
if (!process.waitFor(timeoutMs, TimeUnit.MILLISECONDS)) {View on GitHub (pinned to f82da0b50f)
Solutions
- Read getCause() (the IOException) to see why the process could not start, and verify the shell binary still exists at the configured path.
- Recreate the workspace directory if it was deleted, and check write permissions for the JVM user.
- Check OS limits (ulimit, cgroup pid limits) if process spawning fails under load; then retry the restart.
- As a fallback, discard the session entirely and call initialize(config) to build a brand-new session.
Example fix
// before
try { manager.restartSession(config); } catch (Exception e) { log.error("restart failed", e); }
// after
try { manager.restartSession(config); }
catch (RuntimeException e) {
log.warn("restart failed, reinitializing", e);
manager.initialize(config); // full fresh session as fallback
} Defensive patterns
Strategy: retry
Validate before calling
// Verify environment can spawn a shell before restart:
if (!new File(shellBinary).canExecute()) throw new IllegalStateException("Shell missing: " + shellBinary);
if (!Files.isDirectory(workspace)) throw new IllegalStateException("Workspace gone: " + workspace); Try / catch
try {
manager.restartSession(config);
} catch (RuntimeException e) {
// cause is IOException from process start — fall back to full re-init
manager.initialize(config);
} Prevention
- Keep the shell binary and workspace intact for the lifetime of the session.
- Check container/OS process limits (ulimit -u, cgroup pids) under load.
- Prefer full initialize() over restart() after environmental changes (image updates, moved workspace).
- Log and inspect the wrapped IOException cause to identify spawn failures quickly.
When it happens
Trigger: restartSession() or an internal recovery path triggers session.restart(), and the subsequent process start fails with IOException — e.g. the shell executable is missing, the workspace directory was deleted, or OS resource limits block spawning a new process.
Common situations: Container image lacking the shell binary after a restart; workspace temp directory cleaned up between runs; fork failures under memory/pid pressure (ulimit -u); shell binary path changed after an environment update.
Related errors
- Failed to execute command
- Startup command failed:
- Failed to initialize shell session
- Shell session not initialized. Cannot restart a session that
- Shell session is not running
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/cb29cff59d97d5e0.
Report an issue: GitHub.