alibaba/spring-ai-alibaba · warning
ShellToolAgentHook: No ShellTool2 injected, skipping cleanup
Error message
ShellToolAgentHook: No ShellTool2 injected, skipping cleanup
What it means
ShellToolAgentHook.afterAgent logs this warning and skips cleanup when no ShellTool2 (and thus no ShellSessionManager) is injected. Since no session was ever created in beforeAgent, there is nothing to clean up; the hook returns an empty state delta. Persistent symptom of a mis-wired hook rather than an error in itself.
Source
Thrown at spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/hook/shelltool/ShellToolAgentHook.java:102
log.info("ShellToolAgentHook: Initializing shell session before agent execution");
try {
sessionManager.initialize(config);
log.info("Shell session initialized successfully");
} catch (Exception e) {
log.error("Failed to initialize shell session", e);
throw new RuntimeException("Failed to initialize shell session", e);
}
return CompletableFuture.completedFuture(new HashMap<>());
}
@Override
public CompletableFuture<Map<String, Object>> afterAgent(OverAllState state, RunnableConfig config) {
ShellSessionManager sessionManager = getSessionManager();
if (sessionManager == null) {
log.warn("ShellToolAgentHook: No ShellTool2 injected, skipping cleanup");
return CompletableFuture.completedFuture(new HashMap<>());
}
log.info("ShellToolAgentHook: Cleaning up shell session after agent execution");
try {
sessionManager.cleanup(config);
log.info("Shell session cleaned up successfully");
} catch (Exception e) {
log.error("Failed to cleanup shell session", e);
// Don't throw exception in cleanup to avoid masking original errors
}
return CompletableFuture.completedFuture(new HashMap<>());
}
@Override
public String getName() {View on GitHub (pinned to f82da0b50f)
Solutions
- Inject a ShellTool2 into the hook via the builder and rebuild the agent
- Confirm the registered ToolCallback is extractable as ShellTool2
- If no shell session management is wanted, remove the hook entirely to avoid log noise
- If sessions were created out-of-band, clean them up manually or via a lifecycle manager since this hook will not
Example fix
// before
Agent agent = Agent.builder().hooks(ShellToolAgentHook.builder().build()).build();
// after
Agent agent = Agent.builder()
.tools(shellTool2)
.hooks(ShellToolAgentHook.builder().shellTool2(shellTool2).build())
.build(); Defensive patterns
Strategy: validation
Validate before calling
if (getSessionManager() == null && cleanupRequired) { throw new IllegalStateException("Shell session cleanup requires injected ShellTool2"); } Type guard
boolean hookIsWired(ShellToolAgentHook hook) { return hook.getSessionManager() != null; } Prevention
- Fix the injection at build time — this warning is always downstream of the beforeAgent one
- Unregister the hook if shell tooling is not used, to keep logs clean
- Track session lifecycle externally if sessions are created outside this hook
When it happens
Trigger: Same root cause as the beforeAgent warning: injectTool() was never called or failed with a non-ShellTool2 callback, so getSessionManager() is null when afterAgent runs after agent execution.
Common situations: Same as 1030 — hook registered without ShellTool2; also appears whenever an agent graph runs to completion after the earlier 'skipping initialization' warning.
Understand the failure class
Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.
Related errors
- ShellToolAgentHook: No ShellTool2 injected, skipping initial
- Failed to extract ShellTool2 from tool: {}
- Either chatClient or model must be provided
- Failed to initialize shell session
- SkillRegistry must be provided. Use SkillsAgentHook to load
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/c07901b03c981149.
Report an issue: GitHub.