gastownhall/beads · error
parsing waits-for metadata to set also_blocks: %w
Error message
parsing waits-for metadata to set also_blocks: %w
What it means
NewWaitsForBlockingDependency sets also_blocks=true by round-tripping the dependency's metadata through json.Unmarshal. If the metadata produced by NewWaitsForDependency is not valid JSON, unmarshaling into WaitsForMeta fails with this wrapper.
Source
Thrown at internal/types/types.go:1429
return NewGraphEdgeDependency(issueID, spawnerID, DepWaitsFor, gate, "", "", "", nil)
}
// NewWaitsForBlockingDependency builds a waits-for dependency that also
// carries classic blocking semantics (GH#3783): set also_blocks in the
// metadata so waitsForGateBlockedSQL additionally blocks while the spawner
// itself is open, not only while it has an open parent-child child. Use this
// instead of NewWaitsForDependency exactly when the caller is collapsing a
// would-be DepBlocks edge (from needs/depends_on) into this waits-for edge
// because the two would otherwise collide on the same (source, target) pair
// — never for a plain waits_for with no matching needs/depends_on entry.
func NewWaitsForBlockingDependency(issueID, spawnerID, gate string) (*Dependency, error) {
dep, err := NewWaitsForDependency(issueID, spawnerID, gate)
if err != nil {
return nil, err
}
var meta WaitsForMeta
if err := json.Unmarshal([]byte(dep.Metadata), &meta); err != nil {
return nil, fmt.Errorf("parsing waits-for metadata to set also_blocks: %w", err)
}
meta.AlsoBlocks = true
raw, err := json.Marshal(meta)
if err != nil {
return nil, fmt.Errorf("serializing waits-for also_blocks metadata: %w", err)
}
dep.Metadata = string(raw)
return dep, nil
}
// NewGraphNodeDependency builds the dependency record for a graph-plan node's
// inline dep, shared by the embedded and domain apply paths so their
// resolution semantics cannot drift: an empty type defaults to blocks, and
// the target resolves as a plan-local key first, then as a literal issue ID.
// Waits-for deps carry gate metadata like waits-for edges (all-children
// default, no explicit spawner).
func NewGraphNodeDependency(issueID string, depType DependencyType, target string, keyToID map[string]string) (*Dependency, error) {
if depType == "" {View on GitHub (pinned to 71377f2769)
Solutions
- Rebuild against the current beads version so NewWaitsForDependency emits valid JSON metadata
- Verify dep.Metadata before calling by json.Valid([]byte(dep.Metadata))
- If working with pre-migration-0059 rows that store '{}' or empty metadata, migrate them first
Example fix
// before
dep, _ := NewWaitsForBlockingDependency(issueID, spawnerID, gate) // fails on legacy metadata
// after
// check first
if !json.Valid([]byte(dep.Metadata)) { /* repair metadata or recreate the dependency */ } Defensive patterns
Strategy: validation
Validate before calling
func metadataIsJSON(s string) bool { return json.Valid([]byte(s)) }
// call after building the base dependency:
// if !metadataIsJSON(dep.Metadata) { /* repair or recreate before NewWaitsForBlockingDependency */ } Type guard
func validWaitsForMeta(raw string) bool {
var m types.WaitsForMeta
return json.Unmarshal([]byte(raw), &m) == nil
} Try / catch
dep, err := types.NewWaitsForBlockingDependency(issueID, spawnerID, gate)
if err != nil {
var perr *json.SyntaxError
if errors.As(err, &perr) {
// metadata not parseable: recreate the dependency from scratch
}
return err
} Prevention
- Never hand-edit dependency metadata columns directly
- Run pending migrations before reading/writing waits-for rows
- Round-trip metadata through WaitsForMeta when modifying it
When it happens
Trigger: json.Unmarshal([]byte(dep.Metadata), &meta) failing inside NewWaitsForBlockingDependency, i.e. dep.Metadata holds invalid or non-JSON content.
Common situations: Only possible if the underlying NewGraphEdgeDependency changed what it stores in metadata (e.g. a version where waits-for rows carry '{}' or plain text), or a fork/patch altered metadata format.
Related errors
- re-parsing metadata: %w
- ExternalDoltConfig: must set Socket or (Host, Port)
- failed to parse teams response: %w
- failed to parse projects response: %w
- failed to parse create project response: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/4299df216b55d401.
Report an issue: GitHub.