{"record":{"id":"adb619b5b574fc3c","repo":"wavetermdev/waveterm","slug":"error-deleting-window-w","errorCode":null,"errorMessage":"error deleting window: %w","messagePattern":"error deleting window: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/wcore/window.go","lineNumber":146,"sourceCode":"}\n\n// CloseWindow closes a window and deletes its workspace if it is empty and not named.\n// If fromElectron is true, it does not send an event to Electron.\nfunc CloseWindow(ctx context.Context, windowId string, fromElectron bool) error {\n\tlog.Printf(\"CloseWindow %s\\n\", windowId)\n\twindow, err := GetWindow(ctx, windowId)\n\tif err == nil {\n\t\tlog.Printf(\"got window %s\\n\", windowId)\n\t\tdeleted, _, err := DeleteWorkspace(ctx, window.WorkspaceId, false)\n\t\tif err != nil {\n\t\t\tlog.Printf(\"error deleting workspace: %v\\n\", err)\n\t\t}\n\t\tif deleted {\n\t\t\tlog.Printf(\"deleted workspace %s\\n\", window.WorkspaceId)\n\t\t}\n\t\terr = wstore.DBDelete(ctx, waveobj.OType_Window, windowId)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error deleting window: %w\", err)\n\t\t}\n\t\tlog.Printf(\"deleted window %s\\n\", windowId)\n\t} else {\n\t\tlog.Printf(\"error getting window %s: %v\\n\", windowId, err)\n\t}\n\tclient, err := wstore.DBGetSingleton[*waveobj.Client](ctx)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error getting client: %w\", err)\n\t}\n\tclient.WindowIds = utilfn.RemoveElemFromSlice(client.WindowIds, windowId)\n\terr = wstore.DBUpdate(ctx, client)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error updating client: %w\", err)\n\t}\n\tlog.Printf(\"updated client\\n\")\n\tif !fromElectron {\n\t\teventbus.SendEventToElectron(eventbus.WSEventType{\n\t\t\tEventType: eventbus.WSEvent_ElectronCloseWindow,","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/wcore/window.go#L128-L164","documentation":"CloseWindow removes the Window row via wstore.DBDelete after (attempting to) delete its workspace; this error wraps the delete failure. Note CloseWindow tolerates a missing window (it just logs) but returns this error if the row exists yet cannot be deleted.","triggerScenarios":"wcore.CloseWindow(ctx, windowId, fromElectron) where the window exists (GetWindow succeeded) but DBDelete(ctx, OType_Window, windowId) fails — DB write error, constraint, or corruption.","commonSituations":"DB locked by a concurrent waveterm process; disk full during delete; corrupted DB index preventing row removal; foreign-object cleanup partially failing leaving inconsistent state.","solutions":["Inspect the wrapped %w error for the delete root cause","Check for other waveterm processes locking the DB and stop them","Verify disk space and state-directory permissions","Run CheckAndFixWindow on next startup to reconcile orphaned windows"],"exampleFix":"// before\nerr = wstore.DBDelete(ctx, waveobj.OType_Window, windowId)\nif err != nil {\n\treturn fmt.Errorf(\"error deleting window: %w\", err)\n}\n// after\nif err := wstore.DBDelete(ctx, waveobj.OType_Window, windowId); err != nil {\n\treturn fmt.Errorf(\"error deleting window %s: %w\", windowId, err)\n}","handlingStrategy":"try-catch","validationCode":"if _, err := wcore.GetWindow(ctx, windowId); err != nil {\n\treturn nil // window already gone; nothing to close\n}","typeGuard":null,"tryCatchPattern":"err := wcore.CloseWindow(ctx, windowId, false)\nif err != nil && strings.Contains(err.Error(), \"error deleting window\") {\n\tlog.Printf(\"window row could not be deleted, will retry: %v\", err)\n\t// retry once after checking DB availability\n}","preventionTips":["Ensure only one waveterm process accesses the state DB","Verify DB health (disk space, permissions) before teardown operations","Tolerate CloseWindow errors for already-missing windows — it only errors when the row exists but deletion fails"],"tags":["database","wave-terminal","window-close","persistence"],"backgroundTag":"database-delete-failed","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}