{"record":{"id":"58eb68feefcce14e","repo":"gastownhall/beads","slug":"invalid-set-metadata-expected-key-value-got-q-58eb68","errorCode":null,"errorMessage":"invalid --set-metadata: expected key=value, got %q","messagePattern":"invalid --set-metadata: expected key=value, got %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/metadata.go","lineNumber":293,"sourceCode":"\n// ApplyMetadataEdits applies incremental set (key=value) and unset (key) edits\n// to existing metadata and returns the merged JSON. Set values are typed via\n// MetadataEditValue; keys are validated with ValidateMetadataKey.\nfunc ApplyMetadataEdits(existing json.RawMessage, setFlags, unsetFlags []string) (json.RawMessage, error) {\n\tdata := make(map[string]json.RawMessage)\n\tif len(existing) > 0 {\n\t\ttrimmed := strings.TrimSpace(string(existing))\n\t\tif trimmed != \"\" && trimmed != \"null\" {\n\t\t\tif err := json.Unmarshal(existing, &data); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"existing metadata is not a JSON object: %w\", err)\n\t\t\t}\n\t\t}\n\t}\n\n\tfor _, kv := range setFlags {\n\t\tk, v, ok := strings.Cut(kv, \"=\")\n\t\tif !ok || k == \"\" {\n\t\t\treturn nil, fmt.Errorf(\"invalid --set-metadata: expected key=value, got %q\", kv)\n\t\t}\n\t\tif err := ValidateMetadataKey(k); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tdata[k] = MetadataEditValue(v)\n\t}\n\n\tfor _, k := range unsetFlags {\n\t\tif err := ValidateMetadataKey(k); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tdelete(data, k)\n\t}\n\n\tresult, err := json.Marshal(data)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to marshal metadata: %w\", err)\n\t}","sourceCodeStart":275,"sourceCodeEnd":311,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/metadata.go#L275-L311","documentation":"ApplyMetadataEdits parses each entry of setFlags as key=value using strings.Cut and rejects any entry with no '=' separator or an empty key. The library throws this so malformed --set-metadata flags are caught at edit time rather than silently creating wrong keys. The offending flag is echoed with %q for easy identification.","triggerScenarios":"Passing a set flag like \"mykey\" (no =), \"=value\" (empty key), or \"\" (empty string) in the setFlags slice — e.g. `bd update bd-1 --set-metadata owner` instead of `--set-metadata owner=alice`.","commonSituations":"Shell splitting an argument containing spaces so only part of key=value arrives; forgetting the '=' when the value looks optional; copy-pasting flag docs that show key and value as separate words.","solutions":["Rewrite the flag as key=value: --set-metadata owner=alice.","If the value itself must contain '=', everything after the first '=' is the value (strings.Cut splits only once), so do not escape it.","If the value contains spaces, quote the whole argument: --set-metadata \"note=some text here\".","Check the flag list for empty strings left by over-quoting (e.g. --set-metadata \"\" produces this error)."],"exampleFix":"// before\nbd update bd-1 --set-metadata owner   // no '='\n// after\nbd update bd-1 --set-metadata owner=alice","handlingStrategy":"validation","validationCode":"func validSetFlag(f string) bool {\n    k, _, ok := strings.Cut(f, \"=\")\n    return ok && k != \"\"\n}\n// check every --set-metadata flag in the caller before invoking ApplyMetadataEdits\nfor _, f := range setFlags {\n    if !validSetFlag(f) { return fmt.Errorf(\"bad flag %q\", f) }\n}","typeGuard":null,"tryCatchPattern":"out, err := ApplyMetadataEdits(existing, setFlags, unsetFlags)\nif err != nil && strings.Contains(err.Error(), \"invalid --set-metadata\") {\n    return fmt.Errorf(\"usage: --set-metadata key=value (got: %v)\", err)\n}","preventionTips":["Always write --set-metadata as key=value; quote arguments containing spaces.","Remember only the first '=' splits; values may contain '=' freely.","Check for empty-string flags caused by over-quoting in scripts."],"tags":["cli","metadata","argument-parsing"],"backgroundTag":"invalid-key-value-flag","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}