{"record":{"id":"5441670195e72efa","repo":"alibaba/spring-ai-alibaba","slug":"shell-session-not-initialized-cannot-restart-a-se","errorCode":null,"errorMessage":"Shell session not initialized. Cannot restart a session that does not exist.","messagePattern":"Shell session not initialized\\. Cannot restart a session that does not exist\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/tools/ShellSessionManager.java","lineNumber":310,"sourceCode":"\n\t\treturn new CommandResult(output, result.getExitCode(), result.isTimedOut(),\n\t\t\tresult.isTruncatedByLines(), result.isTruncatedByBytes(),\n\t\t\tresult.getTotalLines(), result.getTotalBytes(), allMatches);\n\t}\n\n\t/**\n\t * Restart the shell session.\n\t * <p>If the session is missing from the context (e.g. after HITL resume),\n\t * it will first attempt to recover from the global registry.</p>\n\t */\n\tpublic void restartSession(RunnableConfig config) {\n\t\tShellSession session = (ShellSession) config.context().get(SESSION_INSTANCE_CONTEXT_KEY);\n\t\tif (session == null) {\n\t\t\t// Try to recover from global registry (HITL resume scenario)\n\t\t\tsession = recoverSessionFromRegistry(config);\n\t\t}\n\t\tif (session == null) {\n\t\t\tthrow new IllegalStateException(\"Shell session not initialized. \" +\n\t\t\t\t\t\"Cannot restart a session that does not exist.\");\n\t\t}\n\n\t\tlog.info(\"Restarting shell session\");\n\t\tsession.restart();\n\n\t\t// Re-run startup commands\n\t\tfor (String command : startupCommands) {\n\t\t\tsession.execute(command, startupTimeout, maxOutputLines, maxOutputBytes);\n\t\t}\n\t}\n\n\tpublic int getMaxOutputLines() {\n\t\treturn maxOutputLines;\n\t}\n\n\t/**\n\t * Clear the global session registry. Package-private for test isolation.","sourceCodeStart":292,"sourceCodeEnd":328,"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#L292-L328","documentation":"restartSession() looks up the existing ShellSession in the run context and, failing that, in the global registry (HITL resume). If no session exists in either place, it throws this IllegalStateException: there is nothing to restart. Restart is defined as stopping and re-starting an existing OS process, so it requires a live session object.","triggerScenarios":"Calling restartSession() before initialize() was ever called for the threadId, after the context was cleared and the global registry entry was removed (e.g. cleanup already ran), or with a mismatched threadId/context so the lookup misses.","commonSituations":"Recovering after a JVM restart where the in-memory registry is empty; calling restartSession() on a brand-new manager; threadId typo so the registry lookup finds nothing; double-cleanup followed by a restart attempt.","solutions":["Call initialize(config) first (fresh session) when you know no session exists, instead of restartSession().","Confirm the threadId and context passed to restartSession() match those used at initialize().","Check whether cleanup() already ran; after cleanup you must re-initialize rather than restart.","Catch IllegalStateException and fall back to initialize() + retry as a recovery path."],"exampleFix":"// before\nif (manager.findSession(threadId) == null) { manager.restartSession(config); } // throws\n\n// after\nif (manager.findSession(threadId) == null) { manager.initialize(config); } else { manager.restartSession(config); }","handlingStrategy":"try-catch","validationCode":"// Only restart when a session actually exists:\nObject session = config.context().get(\"SHELL_SESSION_KEY\");\nif (session == null) manager.initialize(config); else manager.restartSession(config);","typeGuard":null,"tryCatchPattern":"try {\n    manager.restartSession(config);\n} catch (IllegalStateException e) {\n    if (e.getMessage().contains(\"does not exist\")) {\n        manager.initialize(config); // nothing to restart — create fresh\n    }\n}","preventionTips":["Check session existence before calling restartSession().","Remember the registry is in-memory: after JVM restart or cleanup(), you must initialize(), not restart().","Verify threadId consistency; a wrong threadId makes lookups miss and surfaces this error.","Don't call cleanup() followed by restartSession() on the same config."],"tags":["shell","session","restart","illegal-state"],"backgroundTag":"invalid-state-transition","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"}