wavetermdev/waveterm · error
error deleting window: %w
Error message
error deleting window: %w
What it means
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.
Source
Thrown at pkg/wcore/window.go:146
}
// CloseWindow closes a window and deletes its workspace if it is empty and not named.
// If fromElectron is true, it does not send an event to Electron.
func CloseWindow(ctx context.Context, windowId string, fromElectron bool) error {
log.Printf("CloseWindow %s\n", windowId)
window, err := GetWindow(ctx, windowId)
if err == nil {
log.Printf("got window %s\n", windowId)
deleted, _, err := DeleteWorkspace(ctx, window.WorkspaceId, false)
if err != nil {
log.Printf("error deleting workspace: %v\n", err)
}
if deleted {
log.Printf("deleted workspace %s\n", window.WorkspaceId)
}
err = wstore.DBDelete(ctx, waveobj.OType_Window, windowId)
if err != nil {
return fmt.Errorf("error deleting window: %w", err)
}
log.Printf("deleted window %s\n", windowId)
} else {
log.Printf("error getting window %s: %v\n", windowId, err)
}
client, err := wstore.DBGetSingleton[*waveobj.Client](ctx)
if err != nil {
return fmt.Errorf("error getting client: %w", err)
}
client.WindowIds = utilfn.RemoveElemFromSlice(client.WindowIds, windowId)
err = wstore.DBUpdate(ctx, client)
if err != nil {
return fmt.Errorf("error updating client: %w", err)
}
log.Printf("updated client\n")
if !fromElectron {
eventbus.SendEventToElectron(eventbus.WSEventType{
EventType: eventbus.WSEvent_ElectronCloseWindow,View on GitHub (pinned to a4447c1563)
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
Example fix
// before
err = wstore.DBDelete(ctx, waveobj.OType_Window, windowId)
if err != nil {
return fmt.Errorf("error deleting window: %w", err)
}
// after
if err := wstore.DBDelete(ctx, waveobj.OType_Window, windowId); err != nil {
return fmt.Errorf("error deleting window %s: %w", windowId, err)
} Defensive patterns
Strategy: try-catch
Validate before calling
if _, err := wcore.GetWindow(ctx, windowId); err != nil {
return nil // window already gone; nothing to close
} Try / catch
err := wcore.CloseWindow(ctx, windowId, false)
if err != nil && strings.Contains(err.Error(), "error deleting window") {
log.Printf("window row could not be deleted, will retry: %v", err)
// retry once after checking DB availability
} Prevention
- 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
When it happens
Trigger: wcore.CloseWindow(ctx, windowId, fromElectron) where the window exists (GetWindow succeeded) but DBDelete(ctx, OType_Window, windowId) fails — DB write error, constraint, or corruption.
Common situations: 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.
Related errors
- error updating window: %w
- error inserting window: %w
- error updating client: %w
- error inserting client: %w
- error inserting mainserver: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/adb619b5b574fc3c.
Report an issue: GitHub.