{"record":{"id":"335152a47ef2a30d","repo":"gastownhall/beads","slug":"marshaling-metadata-ref-q-w","errorCode":null,"errorMessage":"marshaling metadata ref %q: %w","messagePattern":"marshaling metadata ref %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/types/types.go","lineNumber":1478,"sourceCode":"// MergeMetadataRefs merges resolved metadata_refs into an issue's existing\n// metadata JSON: each refs entry maps a metadata key to a plan-local node\n// key, which is replaced with its minted ID from keyToID. Shared by the\n// embedded and domain graph-apply paths.\nfunc MergeMetadataRefs(existing json.RawMessage, refs map[string]string, keyToID map[string]string) (json.RawMessage, error) {\n\tmerged := make(map[string]json.RawMessage, len(refs))\n\tif len(existing) > 0 {\n\t\tif err := json.Unmarshal(existing, &merged); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"re-parsing metadata: %w\", err)\n\t\t}\n\t}\n\tfor metaKey, refKey := range refs {\n\t\tresolvedID, ok := keyToID[refKey]\n\t\tif !ok {\n\t\t\treturn nil, fmt.Errorf(\"metadata_ref %q references unknown key %q\", metaKey, refKey)\n\t\t}\n\t\tidJSON, err := json.Marshal(resolvedID)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"marshaling metadata ref %q: %w\", metaKey, err)\n\t\t}\n\t\tmerged[metaKey] = idJSON\n\t}\n\treturn json.Marshal(merged)\n}\n\n// ParseWaitsForGateMetadata extracts the waits-for gate type from dependency metadata.\n// Note: spawner identity comes from dependencies.depends_on_id in storage/query paths;\n// metadata.spawner_id is parsed for compatibility/future explicit targeting.\n// Returns WaitsForAllChildren on empty/invalid metadata for backward compatibility.\nfunc ParseWaitsForGateMetadata(metadata string) string {\n\tif strings.TrimSpace(metadata) == \"\" {\n\t\treturn WaitsForAllChildren\n\t}\n\n\tvar meta WaitsForMeta\n\tif err := json.Unmarshal([]byte(metadata), &meta); err != nil {\n\t\treturn WaitsForAllChildren","sourceCodeStart":1460,"sourceCodeEnd":1496,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/types/types.go#L1460-L1496","documentation":"After resolving a metadata ref to its minted ID, MergeMetadataRefs marshals the ID string to JSON (idJSON) for storage; a json.Marshal error is wrapped as 'marshaling metadata ref'.","triggerScenarios":"json.Marshal(resolvedID) returning an error inside MergeMetadataRefs.","commonSituations":"Unreachable in practice — marshaling a Go string to JSON cannot fail; would only occur with a non-standard build or a wrapper type with a faulty MarshalJSON.","solutions":["Rebuild against stock beads to rule out a patched types package","Check for custom marshaler overrides in the metadata path","Report upstream with the inner error if reproducible on a clean build"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"merged, err := types.MergeMetadataRefs(existing, refs, keyToID)\nif err != nil {\n\tif strings.Contains(err.Error(), \"marshaling metadata ref\") {\n\t\tlog.Fatalf(\"metadata ref marshal failed: %v\", err)\n\t}\n\treturn err\n}","preventionTips":["Use a stock build; marshaling a string ID cannot fail normally","Report upstream with the inner error if it reproduces"],"tags":["go","json","serialization","metadata"],"backgroundTag":"json-marshal-failure","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}