{"record":{"id":"08eccc6d3df75145","repo":"gastownhall/beads","slug":"no-slot-q-on-s-no-metadata","errorCode":null,"errorMessage":"no slot %q on %s: no metadata","messagePattern":"no slot %q on (.+?): no metadata","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/dolt/slots.go","lineNumber":97,"sourceCode":"// byte-compatible with the historical whole-metadata rewrite.\nfunc (s *DoltStore) SlotSet(ctx context.Context, issueID, key, value, actor string) error {\n\traw, err := json.Marshal(value)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"marshaling slot value for %s.%s: %w\", issueID, key, err)\n\t}\n\treturn s.MergeMetadata(ctx, issueID, key, raw, actor)\n}\n\n// SlotGet retrieves the value of a metadata key from an issue.\n// Returns an error if the issue has no metadata or the key is not found.\nfunc (s *DoltStore) SlotGet(ctx context.Context, issueID, key string) (string, error) {\n\tissue, err := s.GetIssue(ctx, issueID)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"getting issue %s: %w\", issueID, err)\n\t}\n\n\tif len(issue.Metadata) == 0 {\n\t\treturn \"\", fmt.Errorf(\"no slot %q on %s: no metadata\", key, issueID)\n\t}\n\n\tmetadata := make(map[string]interface{})\n\tif err := json.Unmarshal(issue.Metadata, &metadata); err != nil {\n\t\treturn \"\", fmt.Errorf(\"parsing metadata for %s: %w\", issueID, err)\n\t}\n\n\tval, ok := metadata[key]\n\tif !ok {\n\t\treturn \"\", fmt.Errorf(\"no slot %q on %s: key not found\", key, issueID)\n\t}\n\n\tswitch v := val.(type) {\n\tcase string:\n\t\treturn v, nil\n\tdefault:\n\t\t// Non-string values are returned as JSON\n\t\traw, err := json.Marshal(v)","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dolt/slots.go#L79-L115","documentation":"SlotGet found the issue but its metadata column is empty (zero-length JSON), so no slot key can exist on it. This is a deliberately descriptive 'not found' error telling you the issue has no metadata map at all, as opposed to having metadata without the requested key.","triggerScenarios":"Calling SlotGet on an issue that was never given any metadata (no SlotSet/MergeMetadata ever called on it).","commonSituations":"Reading a slot before ever setting it; querying an old issue created before the slot feature was used; assuming SlotSet ran when it actually failed earlier.","solutions":["Call SlotSet/MergeMetadata to create the slot before reading it.","Treat this as a miss and provide a default value in the caller instead of erroring.","Check with bd or the metadata column whether the issue was expected to carry metadata."],"exampleFix":"// before\nval, err := store.SlotGet(ctx, id, \"owner\")\nif err != nil {\n\treturn err\n}\n// after\nval, err := store.SlotGet(ctx, id, \"owner\")\nif err != nil && strings.Contains(err.Error(), \"no slot\") {\n\tval = \"unassigned\" // default when the issue has no metadata\n}","handlingStrategy":"fallback","validationCode":"issue, err := store.GetIssue(ctx, issueID)\nif err == nil && len(issue.Metadata) == 0 {\n\t// no metadata; skip SlotGet and use a default\n}","typeGuard":null,"tryCatchPattern":"val, err := store.SlotGet(ctx, id, key)\nif err != nil && strings.Contains(err.Error(), \"no metadata\") {\n\tval = defaultValue\n}","preventionTips":["Initialize required slots with SlotSet at issue creation time.","Treat missing metadata as an expected miss and code a default path.","Distinguish this from the key-not-found case by the 'no metadata' suffix."],"tags":["metadata","key-not-found","dolt"],"backgroundTag":"slot-key-not-found","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}