gastownhall/beads · error
unknown dependency type %q; valid types: %s
Error message
unknown dependency type %q; valid types: %s
What it means
The second validateDependencyType branch: the type string is well-formed (non-empty, within length) but not in WellKnownDependencyTypes (blocks, parent-child, conditional-blocks, waits-for, related, discovered-from, ...). `bd create --deps` and `bd dep add` deliberately reject custom dependency types so both commands stay in lockstep; the error lists the valid set.
Source
Thrown at cmd/bd/create_deps.go:189
return types.DepBlocks
default:
return t
}
}
// validateDependencyType enforces that a (post-alias-normalization)
// dependency type is both structurally valid and one of the well-known
// built-in types. `bd create --deps` and `bd dep add --type` intentionally
// reject custom/unknown dependency types (see the comment on
// WellKnownDependencyTypes) — this is the single shared check so both
// commands stay in lockstep.
func validateDependencyType(t types.DependencyType) error {
if !t.IsValid() {
return fmt.Errorf("invalid dependency type %q (must be non-empty, max %d chars); valid types: %s",
t, types.MaxDependencyTypeLen, createDepsAcceptedTypeList())
}
if !t.IsWellKnown() {
return fmt.Errorf("unknown dependency type %q; valid types: %s",
t, createDepsAcceptedTypeList())
}
return nil
}
// buildWaitsFor validates and constructs a WaitsForSpec from the --waits-for
// and --waits-for-gate flag values. gateExplicit must be true when the caller
// explicitly passed --waits-for-gate (not relying on its default); in that case
// a missing spawnerID is rejected rather than silently ignored.
func buildWaitsFor(spawnerID, gate string, gateExplicit bool) (*domain.WaitsForSpec, error) {
spawnerID = strings.TrimSpace(spawnerID)
if spawnerID == "" {
if gateExplicit {
return nil, fmt.Errorf("--waits-for-gate requires --waits-for (no spawner ID specified)")
}
return nil, nil
}
if gate == "" {View on GitHub (pinned to 71377f2769)
Solutions
- Replace the type with one from the printed valid list (blocks, parent-child, conditional-blocks, waits-for, related, discovered-from)
- Use "blocked-by"/"depends-on" aliases if you meant gating semantics — they map to blocks
- If you truly need a custom relation, model it as a related edge plus a label, or via an external reference
Example fix
// before bd dep add bd-1 --type duplicates --target bd-2 // after bd dep add bd-1 --type related --target bd-2
Defensive patterns
Strategy: validation
Validate before calling
var wellKnown = map[string]bool{
"blocks":true, "parent-child":true, "conditional-blocks":true,
"waits-for":true, "related":true, "discovered-from":true,
}
if !wellKnown[strings.TrimSpace(depType)] {
return fmt.Errorf("type %q not accepted by bd; use a built-in", depType)
} Prevention
- Consult the error's valid-types list rather than inventing relations
- Use blocked-by/depends-on aliases for gating semantics
- Model custom relations as related + label, since custom types are rejected by design
When it happens
Trigger: `bd create ... --deps "requires:bd-5"` or `bd dep add bd-1 --type finish-to-start --target bd-2` — any plausible-sounding but non-built-in type, from parseDepSpec, readBulkDepEdges (bulk files), or runDepAddProxiedServer.
Common situations: Users porting habits from other trackers (e.g. "requires", "duplicates", "finish-to-start"); bulk dep files written for an older beads version that allowed custom types; typos like "parent" instead of "parent-child".
Related errors
- invalid dependency type %q (must be non-empty, max %d chars)
- --deps cannot attach both %q and %q to the same target %q: a
- --deps target is empty
- bulk dependency validation failed: %s
- edge %d %s->%s duplicates a parent-child relationship with d
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/e3cbf6b6a5959219.
Report an issue: GitHub.