{"record":{"id":"e319d252abad6330","repo":"wavetermdev/waveterm","slug":"error-getting-window-w-e319d2","errorCode":null,"errorMessage":"error getting window: %w","messagePattern":"error getting window: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/wcore/window.go","lineNumber":29,"sourceCode":"\t\"github.com/google/uuid\"\n\t\"github.com/wavetermdev/waveterm/pkg/eventbus\"\n\t\"github.com/wavetermdev/waveterm/pkg/util/utilfn\"\n\t\"github.com/wavetermdev/waveterm/pkg/waveobj\"\n\t\"github.com/wavetermdev/waveterm/pkg/wshrpc\"\n\t\"github.com/wavetermdev/waveterm/pkg/wshrpc/wshclient\"\n\t\"github.com/wavetermdev/waveterm/pkg/wshutil\"\n\t\"github.com/wavetermdev/waveterm/pkg/wstore\"\n)\n\nfunc SwitchWorkspace(ctx context.Context, windowId string, workspaceId string) (*waveobj.Workspace, error) {\n\tlog.Printf(\"SwitchWorkspace %s %s\\n\", windowId, workspaceId)\n\tws, err := GetWorkspace(ctx, workspaceId)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error getting new workspace: %w\", err)\n\t}\n\twindow, err := GetWindow(ctx, windowId)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error getting window: %w\", err)\n\t}\n\tcurWsId := window.WorkspaceId\n\tif curWsId == workspaceId {\n\t\treturn nil, nil\n\t}\n\n\tallWindows, err := wstore.DBGetAllObjsByType[*waveobj.Window](ctx, waveobj.OType_Window)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error getting all windows: %w\", err)\n\t}\n\n\tfor _, w := range allWindows {\n\t\tif w.WorkspaceId == workspaceId {\n\t\t\tlog.Printf(\"workspace %s already has a window %s, focusing that window\\n\", workspaceId, w.OID)\n\t\t\tclient := wshclient.GetBareRpcClient()\n\t\t\terr = wshclient.FocusWindowCommand(client, w.OID, &wshrpc.RpcOpts{Route: wshutil.ElectronRoute})\n\t\t\treturn nil, err\n\t\t}","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/wcore/window.go#L11-L47","documentation":"SwitchWorkspace loads the window with GetWindow after validating the target workspace. This error wraps a failed window lookup — the windowId does not match an existing Window object or the DB read failed. No workspace switch occurs.","triggerScenarios":"Calling SwitchWorkspace(ctx, windowId, workspaceId) with a windowId that no longer exists (window closed), a malformed/non-UUID windowId, or an underlying DB read error from GetWindow.","commonSituations":"RPC from the frontend racing a window close; stale windowId cached in a client after the window was deleted; startup code running before windows are registered in the store.","solutions":["Confirm the window still exists before switching (re-fetch the window list and re-check the ID)","Use a valid, current window OID from wstore (OType_Window) rather than a cached value","In the caller, treat not-found as benign: skip the switch or create a new window for the workspace","If the wrapped error is a DB error rather than not-found, investigate database health"],"exampleFix":"// before\nws, err := wcore.SwitchWorkspace(ctx, staleWinId, wsId)\n// after\nwin, err := wcore.GetWindow(ctx, winId)\nif errors.Is(err, wstore.ErrNotFound) {\n    win, err = wcore.CreateWindow(ctx, wsId) // create instead of failing\n}","handlingStrategy":"validation","validationCode":"_, err := wcore.GetWindow(ctx, windowId)\nif err != nil {\n    return fmt.Errorf(\"window %s unavailable: %w\", windowId, err)\n}","typeGuard":"func windowExists(ctx context.Context, id string) bool {\n    _, err := wcore.GetWindow(ctx, id)\n    return err == nil\n}","tryCatchPattern":"ws, err := wcore.SwitchWorkspace(ctx, winId, wsId)\nif err != nil && strings.Contains(err.Error(), \"getting window\") {\n    // window is gone; create one for the target workspace\n    ws, err = wcore.CreateWindowForWorkspace(ctx, wsId)\n}","preventionTips":["Subscribe to window-close events and drop stale windowIds","Validate the window exists immediately before switching","Handle races with window close by re-fetching instead of failing","Ensure windowIds come from the current store, not persisted caches"],"tags":["window","not-found","wcore","stale-reference"],"backgroundTag":"window-not-found","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}