{"record":{"id":"877665a014cb49ef","repo":"wavetermdev/waveterm","slug":"tsunami-process-died-before-emitting-listening-mes","errorCode":null,"errorMessage":"tsunami process died before emitting listening message","messagePattern":"tsunami process died before emitting listening message","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/blockcontroller/tsunamicontroller.go","lineNumber":391,"sourceCode":"\t\t\t}\n\t\t}\n\n\t\tclose(waitCh)\n\t}()\n\n\t// Start reading both stdout and stderr\n\tgo lineBuffer.ReadAll(stdoutPipe)\n\tgo lineBuffer.ReadAll(stderrPipe)\n\n\t// Wait for either port detection, process death, or context timeout\n\terrChan := make(chan error, 1)\n\tgo func() {\n\t\t<-tsunamiProc.WaitCh\n\t\tselect {\n\t\tcase <-portChan:\n\t\t\t// Port already found, nothing to do\n\t\tdefault:\n\t\t\terrChan <- fmt.Errorf(\"tsunami process died before emitting listening message\")\n\t\t}\n\t}()\n\n\tselect {\n\tcase port := <-portChan:\n\t\ttsunamiProc.Port = port\n\t\treturn tsunamiProc, nil\n\tcase err := <-errChan:\n\t\tcmd.Process.Kill()\n\t\treturn nil, err\n\tcase <-ctx.Done():\n\t\tcmd.Process.Kill()\n\t\treturn nil, fmt.Errorf(\"timeout waiting for tsunami port: %w\", ctx.Err())\n\t}\n}\n\nfunc MakeTsunamiController(tabId string, blockId string, connName string) Controller {\n\tlog.Printf(\"make tsunami controller: %s %s\\n\", tabId, blockId)","sourceCodeStart":373,"sourceCodeEnd":409,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/blockcontroller/tsunamicontroller.go#L373-L409","documentation":"The tsunami app process exited without ever printing its 'listening' message (from which the HTTP port is parsed). The controller detects this via WaitCh firing before portChan receives a port, so the block fails to start.","triggerScenarios":"App crashes on startup, exits immediately due to bad config/missing deps, or prints an error and dies before binding a port.","commonSituations":"App requires a runtime (Node/Python) that is missing; app's own startup error; incompatibility between app and host platform.","solutions":["Check the captured stderr/stdout buffer for the app's crash message","Run the cached binary manually to see the startup error","Re-download the app to rule out a corrupted build","Verify any required runtimes/env vars for the app are present"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"// smoke-test the binary: run with a short timeout and confirm it emits output instead of exiting immediately","typeGuard":null,"tryCatchPattern":"select {\ncase port := <-portChan:\n\t// ready\ncase err := <-errChan:\n\t// read captured stderr/stdout buffer for the crash reason\n}","preventionTips":["Capture and surface app stderr on startup failure","Keep the last N lines of stdout/stderr for diagnostics","Test apps manually after installing/updating runtimes"],"tags":["process-exit","startup","port"],"backgroundTag":"process-exited-before-ready","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}