{"record":{"id":"411a329e03e61609","repo":"wavetermdev/waveterm","slug":"cannot-start-shellproc-w","errorCode":null,"errorMessage":"cannot start shellproc: %w","messagePattern":"cannot start shellproc: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/blockcontroller/blockcontroller.go","lineNumber":272,"sourceCode":"\n\t\tcase BlockController_Tsunami:\n\t\t\tcontroller = MakeTsunamiController(tabId, blockId, connName)\n\t\t\tregisterController(blockId, controller)\n\n\t\tdefault:\n\t\t\treturn fmt.Errorf(\"unknown controller type %q\", controllerName)\n\t\t}\n\t}\n\n\t// Check if we need to start/restart\n\tstatus := controller.GetRuntimeStatus()\n\tif status.ShellProcStatus == Status_Init {\n\t\t// For shell/cmd, check connection status first (for non-local connections)\n\t\tif controllerName == BlockController_Shell || controllerName == BlockController_Cmd {\n\t\t\tif !conncontroller.IsLocalConnName(connName) {\n\t\t\t\terr = CheckConnStatus(blockId)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn fmt.Errorf(\"cannot start shellproc: %w\", err)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Start controller\n\t\terr = controller.Start(ctx, blockData.Meta, rtOpts, force)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error starting controller: %w\", err)\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc GetBlockControllerRuntimeStatus(blockId string) *BlockControllerRuntimeStatus {\n\tcontroller := getController(blockId)\n\tif controller == nil {\n\t\treturn nil","sourceCodeStart":254,"sourceCodeEnd":290,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/blockcontroller/blockcontroller.go#L254-L290","documentation":"Before starting a shell/cmd controller, ResyncController checks the remote connection state when the block targets a non-local connection. If CheckConnStatus reports the connection is not ready, the failure is wrapped as 'cannot start shellproc: %w'. The shell process was never started because the underlying connection is unavailable.","triggerScenarios":"Starting a shell/cmd block whose meta connection name refers to a remote SSH connection that is disconnected, connecting, or errored — CheckConnStatus returns a non-nil error.","commonSituations":"SSH connection dropped or not yet established when a terminal block auto-restarts on app launch; wrong connName in block meta pointing at a removed connection profile; network down.","solutions":["Ensure the connection is active before opening the block (connect via the connections UI or conncontroller)","Fix the block's meta 'connection' value to a valid, existing connection name or empty for local","Retry the resync after the connection finishes connecting","Check network/SSH credentials if the connection itself fails to establish"],"exampleFix":"// before\n// block meta: { \"connection\": \"old-ssh-profile\" }\n// after\n// reconnect first:\nerr := conncontroller.MakeConn(ctx, \"myserver\")\nif err == nil { ResyncController(ctx, tabId, blockId, rtOpts, false) }","handlingStrategy":"retry","validationCode":"if !conncontroller.IsLocalConnName(connName) {\n    if err := CheckConnStatus(blockId); err != nil { /* wait/reconnect */ }\n}","typeGuard":null,"tryCatchPattern":"for i := 0; i < 3; i++ {\n    if err := ResyncController(ctx, tabId, blockId, rtOpts, false); err == nil || !strings.Contains(err.Error(), \"cannot start shellproc\") { break }\n    time.Sleep(2 * time.Second)\n}","preventionTips":["Reconnect remote connections before restoring terminal blocks","Validate the connection name in block meta exists","Gate startup block restoration on connection readiness"],"tags":["connection","ssh","shell"],"backgroundTag":"connection-not-ready","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}