gastownhall/beads · error
marshaling metadata ref %q: %w
Error message
marshaling metadata ref %q: %w
What it means
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'.
Source
Thrown at internal/types/types.go:1478
// MergeMetadataRefs merges resolved metadata_refs into an issue's existing
// metadata JSON: each refs entry maps a metadata key to a plan-local node
// key, which is replaced with its minted ID from keyToID. Shared by the
// embedded and domain graph-apply paths.
func MergeMetadataRefs(existing json.RawMessage, refs map[string]string, keyToID map[string]string) (json.RawMessage, error) {
merged := make(map[string]json.RawMessage, len(refs))
if len(existing) > 0 {
if err := json.Unmarshal(existing, &merged); err != nil {
return nil, fmt.Errorf("re-parsing metadata: %w", err)
}
}
for metaKey, refKey := range refs {
resolvedID, ok := keyToID[refKey]
if !ok {
return nil, fmt.Errorf("metadata_ref %q references unknown key %q", metaKey, refKey)
}
idJSON, err := json.Marshal(resolvedID)
if err != nil {
return nil, fmt.Errorf("marshaling metadata ref %q: %w", metaKey, err)
}
merged[metaKey] = idJSON
}
return json.Marshal(merged)
}
// ParseWaitsForGateMetadata extracts the waits-for gate type from dependency metadata.
// Note: spawner identity comes from dependencies.depends_on_id in storage/query paths;
// metadata.spawner_id is parsed for compatibility/future explicit targeting.
// Returns WaitsForAllChildren on empty/invalid metadata for backward compatibility.
func ParseWaitsForGateMetadata(metadata string) string {
if strings.TrimSpace(metadata) == "" {
return WaitsForAllChildren
}
var meta WaitsForMeta
if err := json.Unmarshal([]byte(metadata), &meta); err != nil {
return WaitsForAllChildrenView on GitHub (pinned to 71377f2769)
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
Defensive patterns
Strategy: try-catch
Try / catch
merged, err := types.MergeMetadataRefs(existing, refs, keyToID)
if err != nil {
if strings.Contains(err.Error(), "marshaling metadata ref") {
log.Fatalf("metadata ref marshal failed: %v", err)
}
return err
} Prevention
- Use a stock build; marshaling a string ID cannot fail normally
- Report upstream with the inner error if it reproduces
When it happens
Trigger: json.Marshal(resolvedID) returning an error inside MergeMetadataRefs.
Common situations: 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.
Related errors
- ExternalDoltConfig: must set Socket or (Host, Port)
- failed to marshal backup state: %w
- failed to marshal issue %s: %w
- marshaling Linear milestone metadata: %w
- failed to marshal interactions log entry: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/335152a47ef2a30d.
Report an issue: GitHub.