alibaba/spring-ai-alibaba · error · IllegalArgumentException
ShellSessionManager cannot be null
Error message
ShellSessionManager cannot be null
What it means
ShellTool's constructor validates its single dependency: the ShellSessionManager must not be null, since every tool invocation delegates to it for session lookup and command execution. Passing null immediately throws this IllegalArgumentException at construction time rather than failing later with a confusing NullPointerException.
Solutions
- Construct a valid ShellSessionManager before creating the tool and pass it to the constructor.
- If using a factory/builder, check why it returned null (missing config fields, disabled feature) and fix the configuration.
- In Spring wiring, make the manager bean mandatory (@RequiredArgsConstructor injection or @Autowired(required=true)) so context startup fails fast with a clear message.
- Add an explicit null check or Objects.requireNonNull on the manager at your call site for a clearer stack trace.
Example fix
// before ShellSessionManager mgr = buildManagerOrNull(); ShellTool tool = new ShellTool(mgr); // NPE risk / IllegalArgumentException if null // after ShellSessionManager mgr = buildManagerOrNull(); Objects.requireNonNull(mgr, "ShellSessionManager must be configured"); ShellTool tool = new ShellTool(mgr);
Defensive patterns
Strategy: validation
Validate before calling
if (sessionManager == null) {
throw new IllegalStateException("ShellSessionManager must be built before constructing ShellTool");
}
ShellTool tool = new ShellTool(sessionManager); Try / catch
try {
ShellTool tool = new ShellTool(sessionManager);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("cannot be null")) {
// build/lookup a valid ShellSessionManager before retrying
}
} Prevention
- Always construct ShellSessionManager before the tool that depends on it.
- In Spring, use constructor injection so a missing bean fails at startup, not at runtime.
- Never let factory methods silently return null for the manager; throw on misconfiguration instead.
- Add Objects.requireNonNull at your own wiring layer for earlier, clearer failures.
When it happens
Trigger: Calling new ShellTool(null), typically when the manager is produced by a factory/spring bean that returned null, or wiring the tool before the manager was built.
Common situations: Spring @Bean method returning null conditionally; builder/factory for ShellSessionManager silently returning null on misconfiguration; refactoring code where the manager variable was not yet assigned; tests constructing the tool with a mocked null.
Related errors
- ShellSessionManager cannot be null
- Agent name cannot be null or empty
- ChatClient is required
- ChatClient must not be null
- Code must not be null
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/d2103a2f4da80c1c.
Report an issue: GitHub.
Appendix: source
Thrown at spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/tools/ShellTool.java:69
"Execute a shell command inside a persistent session. Before running a command, "
+ "confirm the working directory is correct (e.g., inspect with `ls` or `pwd`) and ensure "
+ "any parent directories exist. Prefer absolute paths and quote paths containing spaces, "
+ "such as `cd \"/path/with spaces\"`. Chain multiple commands with `&&` or `;` instead of "
+ "embedding newlines. Avoid unnecessary `cd` usage unless explicitly required so the "
+ "session remains stable. Outputs may be truncated when they become very large, and long "
+ "running commands will be terminated once their configured timeout elapses.";
private final ShellSessionManager sessionManager;
/**
* Constructs a new ShellTool.
*
* @param sessionManager The manager for the shell session. Must not be null.
*/
public ShellTool(ShellSessionManager sessionManager) {
if (sessionManager == null) {
throw new IllegalArgumentException("ShellSessionManager cannot be null");
}
this.sessionManager = sessionManager;
}
/**
* Defines the parameters for a shell tool request.
*
* @param command The shell command to execute. Can be null if only restarting the session.
* @param restart If true, the shell session will be restarted before executing any command.
*/
public record Request(
@JsonProperty("command")
@JsonPropertyDescription("The command to execute in the shell.")
String command,
@JsonProperty(value = "restart", defaultValue = "false")
@JsonPropertyDescription("Restart the shell session before executing the command.")
Boolean restartView on GitHub (pinned to f82da0b50f)