{"record":{"id":"4c161989bd04d0d0","repo":"gastownhall/beads","slug":"no-slot-q-on-s-key-not-found","errorCode":null,"errorMessage":"no slot %q on %s: key not found","messagePattern":"no slot %q on (.+?): key not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/dolt/slots.go","lineNumber":107,"sourceCode":"// 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)\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"marshaling slot value for %s.%s: %w\", issueID, key, err)\n\t\t}\n\t\treturn string(raw), nil\n\t}\n}\n\n// SlotClear removes a metadata key from an issue.\n// It is not an error to clear a key that doesn't exist.\n//","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dolt/slots.go#L89-L125","documentation":"The issue has valid metadata JSON, but the requested slot key is absent from that JSON object. SlotGet uses the comma-ok map lookup and returns this descriptive error instead of an empty string, distinguishing 'metadata exists, key missing' from the no-metadata case.","triggerScenarios":"Calling SlotGet with a key that was never set via SlotSet/MergeMetadata, or one that was already removed by SlotClear.","commonSituations":"Typo in the slot key (case-sensitive lookup); SlotClear ran earlier; reading an optional slot on issues where only some have it set.","solutions":["Check the key spelling and exact case against what SlotSet wrote.","Set the slot first (SlotSet) or fall back to a default value in the caller.","List the issue's metadata (query the metadata column) to see which keys exist."],"exampleFix":"// before\nval, err := store.SlotGet(ctx, id, \"Owner\") // key was set as \"owner\"\n// after\nval, err := store.SlotGet(ctx, id, \"owner\") // exact key as stored","handlingStrategy":"validation","validationCode":"issue, _ := store.GetIssue(ctx, issueID)\nvar m map[string]interface{}\nif json.Unmarshal(issue.Metadata, &m) == nil {\n\tif _, ok := m[key]; !ok {\n\t\t// key absent; set it or use a default before SlotGet\n\t}\n}","typeGuard":"func slotExists(issue *storage.Issue, key string) bool {\n\tvar m map[string]interface{}\n\tif json.Unmarshal(issue.Metadata, &m) != nil {\n\t\treturn false\n\t}\n\t_, ok := m[key]\n\treturn ok\n}","tryCatchPattern":"val, err := store.SlotGet(ctx, id, key)\nif err != nil && strings.Contains(err.Error(), \"key not found\") {\n\tval = defaultValue\n}","preventionTips":["Define slot keys as constants to avoid typos and case mismatches.","Set optional slots explicitly (even to an empty value) before reading.","Remember SlotClear is lossless removal — re-set keys you still need."],"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"}