{"record":{"id":"77960f4cfbbbfd8a","repo":"wavetermdev/waveterm","slug":"empty-object-reference","errorCode":null,"errorMessage":"empty object reference","messagePattern":"empty object reference","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/wstore/wstore.go","lineNumber":60,"sourceCode":"\nfunc UpdateTabName(ctx context.Context, tabId, name string) error {\n\treturn WithTx(ctx, func(tx *TxWrap) error {\n\t\ttab, _ := DBGet[*waveobj.Tab](tx.Context(), tabId)\n\t\tif tab == nil {\n\t\t\treturn fmt.Errorf(\"tab not found: %q\", tabId)\n\t\t}\n\t\tif tabId != \"\" {\n\t\t\ttab.Name = name\n\t\t\tDBUpdate(tx.Context(), tab)\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc UpdateObjectMeta(ctx context.Context, oref waveobj.ORef, meta waveobj.MetaMapType, mergeSpecial bool) error {\n\treturn WithTx(ctx, func(tx *TxWrap) error {\n\t\tif oref.IsEmpty() {\n\t\t\treturn fmt.Errorf(\"empty object reference\")\n\t\t}\n\t\tobj, _ := DBGetORef(tx.Context(), oref)\n\t\tif obj == nil {\n\t\t\treturn ErrNotFound\n\t\t}\n\t\tobjMeta := waveobj.GetMeta(obj)\n\t\tif objMeta == nil {\n\t\t\tobjMeta = make(map[string]any)\n\t\t}\n\t\tnewMeta := waveobj.MergeMeta(objMeta, meta, mergeSpecial)\n\t\twaveobj.SetMeta(obj, newMeta)\n\t\tDBUpdate(tx.Context(), obj)\n\t\treturn nil\n\t})\n}\n","sourceCodeStart":42,"sourceCodeEnd":76,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/wstore/wstore.go#L42-L76","documentation":"UpdateObjectMeta requires a non-empty waveobj.ORef identifying the object whose metadata should change. An ORef encodes type and ID; an empty one carries no target at all, so the library rejects it up front rather than failing deeper in the transaction.","triggerScenarios":"Passing the zero value of waveobj.ORef (e.g. ORef{} from an unpopulated struct or a failed ParseORef whose error was ignored) into wstore.UpdateObjectMeta.","commonSituations":"Constructing an ORef from an empty oref string field on a partially initialized object; ignoring the error from waveobj.ParseORef and using the zero ORef; default-struct fields never assigned before a meta update.","solutions":["Check oref.IsEmpty() at the call site and skip or fix the caller that produced the empty reference","Validate the source string with waveobj.ParseORef and handle its error instead of discarding it","Ensure the object field carrying the ORef is populated before invoking meta updates"],"exampleFix":"// before\nwstore.UpdateObjectMeta(ctx, oref, meta, true) // oref may be zero\n// after\nif oref.IsEmpty() {\n\treturn nil\n}\nwstore.UpdateObjectMeta(ctx, oref, meta, true)","handlingStrategy":"validation","validationCode":"if oref.IsEmpty() {\n\treturn fmt.Errorf(\"no target object for meta update\")\n}","typeGuard":"func hasORef(oref waveobj.ORef) bool { return !oref.IsEmpty() }","tryCatchPattern":"if err := wstore.UpdateObjectMeta(ctx, oref, meta, true); err != nil {\n\tif strings.Contains(err.Error(), \"empty object reference\") {\n\t\treturn populateORefAndRetry()\n\t}\n\treturn err\n}","preventionTips":["Always build ORefs via waveobj.ParseORef and check its error","Never use the zero-value ORef struct","Validate refs at API boundaries"],"tags":["waveobj","validation","oref"],"backgroundTag":"empty-object-reference","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}