{"record":{"id":"3f4b6e726779fe9c","repo":"wavetermdev/waveterm","slug":"route-did-not-establish-after-successful-reconnect","errorCode":null,"errorMessage":"route did not establish after successful reconnection: %w","messagePattern":"route did not establish after successful reconnection: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/jobcontroller/jobcontroller.go","lineNumber":1155,"sourceCode":"\t\t\t\tProps: telemetrydata.TEventProps{\n\t\t\t\t\tJobDoneReason: JobDoneReason_Gone,\n\t\t\t\t\tJobKind:       job.JobKind,\n\t\t\t\t},\n\t\t\t})\n\t\t\twriteJobTerminationMessage(ctx, jobId, updatedJob, \"[session gone]\")\n\t\t\treturn fmt.Errorf(\"job manager has exited: %s\", rtnData.Error)\n\t\t}\n\t\treturn fmt.Errorf(\"failed to reconnect to job manager: %s\", rtnData.Error)\n\t}\n\n\tlog.Printf(\"[job:%s] RemoteReconnectToJobManagerCommand succeeded, waiting for route\", jobId)\n\n\trouteId := wshutil.MakeJobRouteId(jobId)\n\twaitCtx, cancelFn := context.WithTimeout(ctx, 2*time.Second)\n\tdefer cancelFn()\n\terr = wshutil.DefaultRouter.WaitForRegister(waitCtx, routeId)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"route did not establish after successful reconnection: %w\", err)\n\t}\n\tSetJobConnStatus(jobId, JobConnStatus_Connected)\n\tsendBlockJobStatusEventByJob(ctx, job)\n\n\ttelemetry.GoRecordTEventWrap(&telemetrydata.TEvent{\n\t\tEvent: \"job:reconnect\",\n\t\tProps: telemetrydata.TEventProps{\n\t\t\tJobKind: job.JobKind,\n\t\t},\n\t})\n\n\tlog.Printf(\"[job:%s] route established, restarting streaming\", jobId)\n\treturn restartStreaming(ctx, jobId, true, rtOpts)\n}\n\nfunc ReconnectJobsForConn(ctx context.Context, connName string) error {\n\tisConnected, err := conncontroller.IsConnected(connName)\n\tif err != nil {","sourceCodeStart":1137,"sourceCodeEnd":1173,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/jobcontroller/jobcontroller.go#L1137-L1173","documentation":"This error is returned when the remote reconnect RPC reported success but the local wshutil.DefaultRouter never saw the job's route register within the 2-second window (jobcontroller.go:1155). WaitForRegister(waitCtx, routeId) times out or fails, meaning the job manager never finished establishing its message route back to this server despite the reconnect command nominally succeeding.","triggerScenarios":"wshutil.DefaultRouter.WaitForRegister(ctx, wshutil.MakeJobRouteId(jobId)) returns error (context deadline exceeded after 2s) after a successful RemoteReconnectToJobManagerCommand — the remote accepted the reconnect but the job route never registered locally.","commonSituations":"1) Slow remote/network where the job manager needs >2s to spin up and register its route. 2) The job manager died right after accepting the reconnect. 3) Message routing issues between the remote daemon and main server (websocket hiccup).","solutions":["Retry ReconnectJob — a second attempt often succeeds once the route settles.","Increase tolerance by retrying with backoff rather than treating it as fatal immediately.","Check that the websocket/connection stayed up during the 2s window (look for conn drops in logs).","If persistent, verify the remote job manager process is actually alive on the host."],"exampleFix":"// before\nerr := jobcontroller.ReconnectJob(ctx, jobId, nil) // may fail: route timeout\n// after\nvar err error\nfor i := 0; i < 3; i++ {\n    if err = jobcontroller.ReconnectJob(ctx, jobId, nil); err == nil {\n        break\n    }\n    if !strings.Contains(err.Error(), \"route did not establish\") {\n        break\n    }\n    time.Sleep(500 * time.Millisecond)\n}","handlingStrategy":"retry","validationCode":"// verify the conn/websocket stayed up before/after reconnect attempt","typeGuard":null,"tryCatchPattern":"if err := jobcontroller.ReconnectJob(ctx, jobId, nil); err != nil && strings.Contains(err.Error(), \"route did not establish\") {\n    // transient: retry after short delay\n    time.Sleep(500 * time.Millisecond)\n    err = jobcontroller.ReconnectJob(ctx, jobId, nil)\n}","preventionTips":["Retry route-establishment failures — they are often timing-related","Monitor conn stability; drops during the 2s window cause this","Avoid heavy network load during reconnect windows"],"tags":["go","routing","timeout"],"backgroundTag":"route-registration-timeout","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}