{"record":{"id":"d0fb9ba028836aed","repo":"wavetermdev/waveterm","slug":"error-getting-client-w","errorCode":null,"errorMessage":"error getting client: %w","messagePattern":"error getting client: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/wcore/window.go","lineNumber":120,"sourceCode":"\t\t}\n\t}\n\twindow := &waveobj.Window{\n\t\tOID:         windowId,\n\t\tWorkspaceId: ws.OID,\n\t\tIsNew:       true,\n\t\tPos: waveobj.Point{\n\t\t\tX: 0,\n\t\t\tY: 0,\n\t\t},\n\t\tWinSize: *winSize,\n\t}\n\terr := wstore.DBInsert(ctx, window)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error inserting window: %w\", err)\n\t}\n\tclient, err := GetClientData(ctx)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error getting client: %w\", err)\n\t}\n\tclient.WindowIds = append(client.WindowIds, windowId)\n\terr = wstore.DBUpdate(ctx, client)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error updating client: %w\", err)\n\t}\n\treturn GetWindow(ctx, windowId)\n}\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 {","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/wcore/window.go#L102-L138","documentation":"After inserting the window, CreateWindow reads the singleton Client record via GetClientData to append the new windowId; this error wraps a failure reading that client record. The window row already exists at this point, so a failure here leaves a partially-created window.","triggerScenarios":"wcore.CreateWindow when GetClientData(ctx) fails — the client singleton is missing from the DB (fresh/uninitialized DB where EnsureInitialData never ran) or the singleton read errors.","commonSituations":"Calling CreateWindow before EnsureInitialData on a brand-new install; DB reset/corruption removing the client singleton; read error on the state DB.","solutions":["Ensure wcore.EnsureInitialData has run before creating windows","Check the wrapped %w error — 'not found' means the client singleton is missing","Re-initialize the client data or restore the DB","Clean up the already-inserted window row if aborting"],"exampleFix":"// before\nclient, err := GetClientData(ctx)\nif err != nil {\n\treturn nil, fmt.Errorf(\"error getting client: %w\", err)\n}\n// after\nclient, err := GetClientData(ctx)\nif err != nil {\n\t_ = wstore.DBDelete(ctx, waveobj.OType_Window, windowId) // roll back partial creation\n\treturn nil, fmt.Errorf(\"error getting client (is client data initialized?): %w\", err)\n}","handlingStrategy":"validation","validationCode":"if _, err := wcore.GetClientData(ctx); err != nil {\n\tif err := wcore.EnsureInitialData(); err != nil {\n\t\treturn fmt.Errorf(\"client data unavailable: %w\", err)\n\t}\n}","typeGuard":null,"tryCatchPattern":"win, err := wcore.CreateWindow(ctx, winSize, workspaceId)\nif err != nil && strings.Contains(err.Error(), \"error getting client\") {\n\t// window row may exist but be unregistered; run CheckAndFixWindow or re-init\n\tif initErr := wcore.EnsureInitialData(); initErr != nil {\n\t\treturn initErr\n\t}\n\treturn err\n}","preventionTips":["Always call EnsureInitialData at startup before window operations","Never delete or hand-edit the client singleton row","Guard against multiple initialization paths racing at launch"],"tags":["wave-terminal","client-data","window-creation","initialization"],"backgroundTag":"missing-client-singleton","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}