{"record":{"id":"604ec96831c9693a","repo":"wavetermdev/waveterm","slug":"error-getting-all-windows-w","errorCode":null,"errorMessage":"error getting all windows: %w","messagePattern":"error getting all windows: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/wcore/window.go","lineNumber":38,"sourceCode":"\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}\n\t}\n\twindow.WorkspaceId = workspaceId\n\terr = wstore.DBUpdate(ctx, window)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error updating window: %w\", err)\n\t}\n\n\tdeleted, _, err := DeleteWorkspace(ctx, curWsId, false)\n\tif err != nil && deleted {","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/wcore/window.go#L20-L56","documentation":"SwitchWorkspace enumerates all Window objects with wstore.DBGetAllObjsByType to enforce that one workspace is owned by at most one window. This error wraps a failure of that enumeration (DB read error), preventing the switch from proceeding even though both the workspace and window were found.","triggerScenarios":"wstore.DBGetAllObjsByType[*waveobj.Window](ctx, waveobj.OType_Window) returns an error during SwitchWorkspace — SQLite read failure, DB locked by another process, corruption, or the 5s-style context deadline expiring during the query.","commonSituations":"Concurrent Wave client processes contending for the DB; disk I/O errors; large/corrupt wave.db; storage pressure making reads slow enough to hit the context timeout.","solutions":["Check the wrapped cause for 'database is locked' and close other Wave processes holding the DB","Fix underlying storage problems (disk full, permissions, I/O errors) indicated by the wrapped error","Retry the switch after transient DB errors; the operation is read-mostly and idempotent until the update step","If wave.db is corrupt, back it up and remove it (windows/workspaces will be recreated)"],"exampleFix":"// caller-side retry\nvar ws *waveobj.Workspace\nerr := retry(3, func() error {\n    var e error\n    ws, e = wcore.SwitchWorkspace(ctx, winId, wsId)\n    return e\n})","handlingStrategy":"retry","validationCode":"// check DB reachable before batch operations\nif err := wstore.DBGetAllObjsByType[*waveobj.Window](ctx, waveobj.OType_Window); err != nil {\n    log.Printf(\"window enumeration unhealthy: %v\", err)\n}","typeGuard":null,"tryCatchPattern":"err := wcore.SwitchWorkspace(ctx, winId, wsId)\nfor i := 0; err != nil && strings.Contains(err.Error(), \"getting all windows\") && i < 3; i++ {\n    time.Sleep(300 * time.Millisecond)\n    err = wcore.SwitchWorkspace(ctx, winId, wsId)\n}","preventionTips":["Run a single app process per wave.db to avoid lock contention","Keep adequate disk space and healthy storage I/O","Use contexts with generous timeouts for DB-heavy operations","Monitor and alert on SQLite lock/corruption errors in logs"],"tags":["window","database","enumeration","wcore"],"backgroundTag":"database-read-failed","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}