{"record":{"id":"2e07d66531e1f4c7","repo":"alibaba/spring-ai-alibaba","slug":"shellsessionmanager-cannot-be-null-2e07d6","errorCode":null,"errorMessage":"ShellSessionManager cannot be null","messagePattern":"ShellSessionManager cannot be null","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/tools/ShellTool2.java","lineNumber":70,"sourceCode":"\tpublic static final String DEFAULT_TOOL_DESCRIPTION =\n\t\t\t\"Execute a shell command inside a persistent session. Before running a command, \"\n\t\t\t\t\t+ \"confirm the working directory is correct (e.g., inspect with `ls` or `pwd`) and ensure \"\n\t\t\t\t\t+ \"any parent directories exist. Prefer absolute paths and quote paths containing spaces, \"\n\t\t\t\t\t+ \"such as `cd \\\"/path/with spaces\\\"`. Chain multiple commands with `&&` or `;` instead of \"\n\t\t\t\t\t+ \"embedding newlines. Avoid unnecessary `cd` usage unless explicitly required so the \"\n\t\t\t\t\t+ \"session remains stable. Outputs may be truncated when they become very large, and long \"\n\t\t\t\t\t+ \"running commands will be terminated once their configured timeout elapses.\";\n\n\tprivate final ShellSessionManager sessionManager;\n\n\t/**\n\t * Constructs a new ShellTool2.\n\t *\n\t * @param sessionManager The manager for the shell session. Must not be null.\n\t */\n\tpublic ShellTool2(ShellSessionManager sessionManager) {\n\t\tif (sessionManager == null) {\n\t\t\tthrow new IllegalArgumentException(\"ShellSessionManager cannot be null\");\n\t\t}\n\t\tthis.sessionManager = sessionManager;\n\t}\n\n\t// @formatter:off\n\t@Tool(name = \"shell\", description = DEFAULT_TOOL_DESCRIPTION)\n\tpublic String executeShellCommand(\n\t\t@ToolParam(description = \"The command to execute in the shell.\") String command,\n\t\t@ToolParam(description = \"Restart the shell session before executing the command (default: false).\", required = false) Boolean restart,\n\t\tToolContext toolContext) { // @formatter:on\n\n\t\ttry {\n\t\t\tRunnableConfig config = (RunnableConfig) toolContext.getContext().get(AGENT_CONFIG_CONTEXT_KEY);\n\t\t\t\n\t\t\t// Handle restart request\n\t\t\tif (Boolean.TRUE.equals(restart)) {\n\t\t\t\tlog.info(\"Restarting shell session as requested.\");\n\t\t\t\tsessionManager.restartSession(config);","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/alibaba/spring-ai-alibaba/blob/f82da0b50f35744c13968191be2b1cd2452ef550/spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/tools/ShellTool2.java#L52-L88","documentation":"Identical guard to ShellTool: ShellTool2's constructor requires a non-null ShellSessionManager and throws this IllegalArgumentException when null is passed. ShellTool2 is the second-generation variant of the shell tool, and all of its shell operations depend on this manager.","triggerScenarios":"Calling new ShellTool2(null) — usually because the manager came from a conditional factory, an optional Spring injection point, or a variable assigned later in the code path.","commonSituations":"Migrating from ShellTool to ShellTool2 and wiring the new tool before the manager bean exists; @Autowired(required=false) leaving the field null in tests; configuration disabled the shell feature so the manager was never created.","solutions":["Create and pass a fully configured ShellSessionManager to the ShellTool2 constructor.","Fix the factory/builder that returned null (missing required configuration for the shell feature).","In Spring, inject the manager as a required dependency so startup fails fast instead of passing null at runtime.","Guard with Objects.requireNonNull at the construction site for an earlier, clearer failure."],"exampleFix":"// before\n@Autowired(required = false)\nprivate ShellSessionManager sessionManager;\nShellTool2 tool = new ShellTool2(sessionManager); // null if bean absent\n\n// after\n@Autowired\nprivate ShellSessionManager sessionManager; // required bean\nShellTool2 tool = new ShellTool2(sessionManager);","handlingStrategy":"validation","validationCode":"if (sessionManager == null) {\n    throw new IllegalStateException(\"ShellSessionManager must be built before constructing ShellTool2\");\n}\nShellTool2 tool = new ShellTool2(sessionManager);","typeGuard":null,"tryCatchPattern":"try {\n    ShellTool2 tool = new ShellTool2(sessionManager);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"cannot be null\")) {\n        // build/lookup a valid ShellSessionManager before retrying\n    }\n}","preventionTips":["Wire the manager as a required dependency when migrating from ShellTool to ShellTool2.","Avoid @Autowired(required=false) for ShellSessionManager; prefer required constructor injection.","Verify the shell feature is enabled in configuration so the manager bean is actually created.","Add a null assertion at the wiring layer before tool construction."],"tags":["null-check","constructor","shell","wiring"],"backgroundTag":"null-argument","analyzedSha":"f82da0b50f35744c13968191be2b1cd2452ef550","analyzedAt":"2026-09-09T15:32:42.421Z","contentChangedAt":"2026-09-09T15:32:42.421Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}