{"record":{"id":"bb7104aeea8a801c","repo":"wavetermdev/waveterm","slug":"server-is-no-longer-running-cannot-send-new-reque","errorCode":null,"errorMessage":"server is no longer running, cannot send new requests","messagePattern":"server is no longer running, cannot send new requests","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/wshutil/wshrpc.go","lineNumber":765,"sourceCode":"func (handler *RpcResponseHandler) Finalize() {\n\t// Always unregister the handler from the map, even if already done\n\tif handler.reqId != \"\" {\n\t\thandler.w.unregisterResponseHandler(handler.reqId)\n\t}\n\tif handler.done.Load() {\n\t\treturn\n\t}\n\t// SendResponse with done=true will call close() via defer, even when reqId is empty\n\thandler.SendResponse(nil, true)\n}\n\nfunc (handler *RpcResponseHandler) IsDone() bool {\n\treturn handler.done.Load()\n}\n\nfunc (w *WshRpc) SendComplexRequest(command string, data any, opts *wshrpc.RpcOpts) (rtnHandler *RpcRequestHandler, rtnErr error) {\n\tif w.IsServerDone() {\n\t\treturn nil, errors.New(\"server is no longer running, cannot send new requests\")\n\t}\n\tif opts == nil {\n\t\topts = &wshrpc.RpcOpts{}\n\t}\n\ttimeoutMs := opts.Timeout\n\tif timeoutMs <= 0 {\n\t\ttimeoutMs = DefaultTimeoutMs\n\t}\n\tdefer func() {\n\t\tpanichandler.PanicHandler(\"SendComplexRequest\", recover())\n\t}()\n\tif command == \"\" {\n\t\treturn nil, fmt.Errorf(\"command cannot be empty\")\n\t}\n\thandler := &RpcRequestHandler{\n\t\tw:           w,\n\t\tctxCancelFn: &atomic.Pointer[context.CancelFunc]{},\n\t}","sourceCodeStart":747,"sourceCodeEnd":783,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/wshutil/wshrpc.go#L747-L783","documentation":"WshRpc refuses to send new requests once its server has been marked done (IsServerDone). This guards against writing onto a dead/closed connection and fails fast instead of hanging on a response that will never arrive.","triggerScenarios":"Calling w.SendComplexRequest (or wrappers like SendRpc/SendComplexRequestTimeOut) after the WshRpc instance's server side has been shut down/closed (done flag set, e.g. connection teardown or process exit).","commonSituations":"Issuing commands from a goroutine while the terminal/block connection closes; calling wsh clients after app shutdown; long-lived background tasks outliving their connection.","solutions":["Check w.IsServerDone() (or connection state) before sending; skip or re-establish the connection first.","Recreate the client/connection and retry the request after reconnecting.","Restructure code so all RPCs complete before shutdown, or cancel in-flight work at teardown.","Add a guard in your wrapper that converts this error into a reconnect-and-retry flow.","Avoid holding WshRpc references beyond the owning component's lifetime."],"exampleFix":"// before\nresp, err := wshobj.SendComplexRequestTimeOut(ctx, \"wave:info\", opts, 3000) // panics-style hard error after close\n// after\nif wshobj.IsServerDone() {\n    return fmt.Errorf(\"connection closed, skipping request\")\n}\nresp, err := wshobj.SendComplexRequestTimeOut(ctx, \"wave:info\", opts, 3000)","handlingStrategy":"validation","validationCode":"if w.IsServerDone() {\n    return fmt.Errorf(\"skipping %s: server closed\", command)\n}","typeGuard":null,"tryCatchPattern":"hdl, err := w.SendComplexRequest(command, data, opts)\nif err != nil && strings.Contains(err.Error(), \"server is no longer running\") {\n    w = reconnect(); hdl, err = w.SendComplexRequest(command, data, opts)\n}","preventionTips":["Gate all sends on IsServerDone()/connection-alive checks.","Stop background senders during shutdown before closing the server.","Recreate WshRpc clients after connection loss instead of reusing them.","Scope client references to the owning component's lifetime."],"tags":["go","rpc","shutdown"],"backgroundTag":"rpc-server-shutdown","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}