{"record":{"id":"f0a8f3fd73a33e51","repo":"alibaba/spring-ai-alibaba","slug":"startup-command-failed","errorCode":null,"errorMessage":"Startup command failed: ","messagePattern":"Startup command failed: ","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/tools/ShellSessionManager.java","lineNumber":140,"sourceCode":"\n\t\t\tShellSession session = new ShellSession(workspace, shellCommand, environment, terminationTimeout);\n\t\t\tsession.start();\n\t\t\tconfig.context().put(SESSION_INSTANCE_CONTEXT_KEY, session);\n\n\t\t\t// Register in global registry for HITL recovery\n\t\t\tfinal Path finalWorkspace = workspace;\n\t\t\tconfig.threadId().ifPresent(threadId -> {\n\t\t\t\tSESSION_REGISTRY.put(threadId, new SessionEntry(session, finalWorkspace));\n\t\t\t\tlog.debug(\"Registered shell session in global registry with threadId: {}\", threadId);\n\t\t\t});\n\n\t\t\tlog.info(\"Started shell session in workspace: {}\", workspace);\n\n\t\t\t// Run startup commands\n\t\t\tfor (String command : startupCommands) {\n\t\t\t\tCommandResult result = session.execute(command, startupTimeout, maxOutputLines, maxOutputBytes);\n\t\t\t\tif (result.isTimedOut() || (result.getExitCode() != null && result.getExitCode() != 0)) {\n\t\t\t\t\tthrow new RuntimeException(\"Startup command failed: \" + command + \", exit code: \" + result.getExitCode());\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (Exception e) {\n\t\t\tcleanup(config);\n\t\t\tthrow new RuntimeException(\"Failed to initialize shell session\", e);\n\t\t}\n\t}\n\n\t/**\n\t * Clean up shell session.\n\t * This removes the session from both the context and the global registry.\n\t */\n\tpublic void cleanup(RunnableConfig config) {\n\t\ttry {\n\t\t\t// Try to get session from context first, then from registry\n\t\t\tShellSession session = (ShellSession) config.context().get(SESSION_INSTANCE_CONTEXT_KEY);\n\t\t\tif (session == null) {\n\t\t\t\tsession = getSessionFromRegistry(config);","sourceCodeStart":122,"sourceCodeEnd":158,"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/ShellSessionManager.java#L122-L158","documentation":"During ShellSessionManager.initialize(), each configured startup command is executed in the new shell session. If a command times out or exits with a non-zero exit code, the manager throws this RuntimeException naming the command and its exit code, then aborts session creation. It exists so a broken startup script fails fast instead of leaving a half-initialized session.","triggerScenarios":"A startup command in the configured startupCommands list returns exit code != 0, or exceeds startupTimeout and is reported as timed out, while initialize() runs (directly or via beforeAgent hook / executeCommand lazy init).","commonSituations":"Typo or wrong path in a startup command like 'cd /nonexistent'; 'source venv/bin/activate' failing because the venv does not exist in the workspace; commands that require TTY interaction; startupTimeout too short for slow commands (package installs, container boots).","solutions":["Run the failing command manually in an equivalent shell to see why it exits non-zero, and fix it (correct path, missing file, permissions).","Increase the startupTimeout configuration if the command is legitimate but slow.","Remove or make fault-tolerant non-essential startup commands, e.g. append '|| true' so a non-zero exit does not abort session init.","Catch the RuntimeException and inspect the message (it includes the command and exit code) to identify which startup command failed."],"exampleFix":"// before\nconfig.setStartupCommands(List.of(\"source /app/venv/bin/activate\"));\n\n// after\nconfig.setStartupCommands(List.of(\"source /app/venv/bin/activate || true\")); // tolerate missing venv\n// or increase timeout\nconfig.setStartupTimeout(60_000L);","handlingStrategy":"validation","validationCode":"// Before startup, verify each command succeeds standalone:\nfor (String cmd : startupCommands) {\n    Process p = new ProcessBuilder(\"sh\", \"-c\", cmd).start();\n    if (p.waitFor() != 0) throw new IllegalStateException(\"Startup command will fail: \" + cmd);\n}","typeGuard":null,"tryCatchPattern":"try {\n    manager.initialize(config);\n} catch (RuntimeException e) {\n    if (e.getMessage().startsWith(\"Startup command failed\")) {\n        // e.getMessage() names the failing command and exit code; fix or drop it\n    }\n}","preventionTips":["Test each startup command manually in the same container/image before adding it to startupCommands.","Append '|| true' to non-critical startup commands so a non-zero exit does not abort initialization.","Set startupTimeout generously for slow commands (installs, service boots).","Keep startup commands idempotent and non-interactive (no TTY prompts)."],"tags":["shell","process","startup","exit-code","timeout"],"backgroundTag":"startup-command-failed","analyzedSha":"f82da0b50f35744c13968191be2b1cd2452ef550","analyzedAt":"2026-09-09T15:32:42.421Z","contentChangedAt":"2026-09-09T15:32:42.421Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}