{"record":{"id":"b33ed261bfd5a947","repo":"wavetermdev/waveterm","slug":"error-getting-client-data-w-b33ed2","errorCode":null,"errorMessage":"error getting client data: %w","messagePattern":"error getting client data: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/wcore/wcore.go","lineNumber":103,"sourceCode":"\treturn firstLaunch, nil\n}\n\nfunc CreateClient(ctx context.Context) (*waveobj.Client, error) {\n\tclient := &waveobj.Client{\n\t\tOID:       uuid.NewString(),\n\t\tWindowIds: []string{},\n\t}\n\terr := wstore.DBInsert(ctx, client)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error inserting client: %w\", err)\n\t}\n\treturn client, nil\n}\n\nfunc GetClientData(ctx context.Context) (*waveobj.Client, error) {\n\tclientData, err := wstore.DBGetSingleton[*waveobj.Client](ctx)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error getting client data: %w\", err)\n\t}\n\treturn clientData, nil\n}\n\nfunc SendWaveObjUpdate(oref waveobj.ORef) {\n\tctx, cancelFn := context.WithTimeout(context.Background(), 2*time.Second)\n\tdefer cancelFn()\n\t// send a waveobj:update event\n\twaveObj, err := wstore.DBGetORef(ctx, oref)\n\tif err != nil {\n\t\tlog.Printf(\"error getting object for update event: %v\", err)\n\t\treturn\n\t}\n\twps.Broker.Publish(wps.WaveEvent{\n\t\tEvent:  wps.Event_WaveObjUpdate,\n\t\tScopes: []string{oref.String()},\n\t\tData: waveobj.WaveObjUpdate{\n\t\t\tUpdateType: waveobj.UpdateType_Update,","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/wcore/wcore.go#L85-L121","documentation":"Returned when fetching a client's data from the store fails. The underlying error is wrapped with %w.","triggerScenarios":"wstore.DBGetSingleton[*waveobj.Client] fails — the client record does not exist yet (called before EnsureInitialData/CreateClient), the DB query errors, or multiple/unexpected singleton rows exist.","commonSituations":"Calling GetClientData or CreateWindow/FocusWindow before initialization completed; DB corrupted or wiped mid-session; a race between two startup paths.","solutions":["Ensure EnsureInitialData ran before fetching client data","Check the wrapped error: ErrNotFound means the client record is missing","Recreate the client record via a clean relaunch (fresh DB init)","Verify only one Wave process is using the DB"],"exampleFix":"// before\nclient, err := wcore.GetClientData(ctx)\n// after\nclient, err := wcore.GetClientData(ctx)\nif errors.Is(err, wstore.ErrNotFound) {\n    _, err = wcore.EnsureInitialData(ctx)\n}","handlingStrategy":"try-catch","validationCode":"err := wstore.WithAuthR(ctx, func(ctx context.Context) error {\n    _, err := wstore.DBGetSingleton[*waveobj.Client](ctx)\n    return err\n})\n// if errors.Is(err, wstore.ErrNotFound) run EnsureInitialData first","typeGuard":"func clientReady(ctx context.Context) bool {\n    _, err := wstore.DBGetSingleton[*waveobj.Client](ctx)\n    return err == nil\n}","tryCatchPattern":"client, err := wcore.GetClientData(ctx)\nif errors.Is(err, wstore.ErrNotFound) {\n    _, err = wcore.EnsureInitialData(ctx)\n}","preventionTips":["Always run EnsureInitialData before touching client data","Check for ErrNotFound to distinguish missing vs broken DB","Serialize startup across goroutines","Guard against double initialization"],"tags":["database","client"],"backgroundTag":"record-not-found","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}