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

  1. Inject a ShellTool2 into the hook via the builder and rebuild the agent
  2. Confirm the registered ToolCallback is extractable as ShellTool2
  3. If no shell session management is wanted, remove the hook entirely to avoid log noise
  4. 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

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


AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09). Data as JSON: /api/errors/c07901b03c981149. Report an issue: GitHub.