wavetermdev/waveterm · error
error updating client
Error message
error updating client: %w
What it means
CreateWindow appends the new windowId to client.WindowIds and persists the Client singleton via wstore.DBUpdate; this error wraps the update failure. The window is already inserted, so failure here leaves an inconsistent state (window exists but is not registered with the client).
Solutions
- Check the wrapped %w error for the write failure root cause
- Verify no second waveterm instance holds a lock on the DB
- Clean up the orphaned window row (DBDelete) since client registration failed
- Retry CreateWindow once the DB is writable
Example fix
// before
err = wstore.DBUpdate(ctx, client)
if err != nil {
return nil, fmt.Errorf("error updating client: %w", err)
}
// after
if err := wstore.DBUpdate(ctx, client); err != nil {
_ = wstore.DBDelete(ctx, waveobj.OType_Window, windowId) // roll back orphaned window
return nil, fmt.Errorf("error updating client: %w", err)
} Defensive patterns
Strategy: try-catch
Validate before calling
if _, err := wcore.GetClientData(ctx); err != nil {
return fmt.Errorf("client record unreadable before window creation: %w", err)
} Try / catch
win, err := wcore.CreateWindow(ctx, winSize, workspaceId)
if err != nil && strings.Contains(err.Error(), "error updating client") {
// window inserted but not registered — clean up orphan
log.Printf("partial window creation: %v", err)
return err
} Prevention
- Serialize window creation (mutex) to avoid racing on the Client singleton
- Run a single waveterm process per state directory
- Reconcile client.WindowIds against actual windows on startup
When it happens
Trigger: wcore.CreateWindow where DBUpdate(ctx, client) fails after a successful read — DB write error, disk full, or the client record was deleted concurrently between read and update.
Common situations: Disk-full or permission issues mid-launch; concurrent window creation from multiple clients racing on the same Client singleton row; DB locked by another waveterm process.
Related errors
- error creating workspace
- error deleting window
- error deleting workspace
- error getting client
- error inserting window
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/2d9d185a468d088e.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/wcore/window.go:125
IsNew: true,
Pos: waveobj.Point{
X: 0,
Y: 0,
},
WinSize: *winSize,
}
err := wstore.DBInsert(ctx, window)
if err != nil {
return nil, fmt.Errorf("error inserting window: %w", err)
}
client, err := GetClientData(ctx)
if err != nil {
return nil, fmt.Errorf("error getting client: %w", err)
}
client.WindowIds = append(client.WindowIds, windowId)
err = wstore.DBUpdate(ctx, client)
if err != nil {
return nil, fmt.Errorf("error updating client: %w", err)
}
return GetWindow(ctx, windowId)
}
// 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)
}View on GitHub (pinned to a4447c1563)