gastownhall/beads · error
invalid dependency type %q (must be non-empty, max %d chars)
Error message
invalid dependency type %q (must be non-empty, max %d chars); valid types: %s
What it means
validateDependencyType is the single shared gate used by `bd create --deps` and `bd dep add`: custom/unknown dependency types are intentionally rejected, only well-known built-ins are accepted. This first branch fires when the type fails basic IsValid() checks — empty, or longer than types.MaxDependencyTypeLen.
Source
Thrown at cmd/bd/create_deps.go:185
// like "parent-child" and custom types) passes through unchanged.
func canonicalDependencyType(t types.DependencyType) types.DependencyType {
switch t {
case "depends-on", "blocked-by":
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)")View on GitHub (pinned to 71377f2769)
Solutions
- Use one of the accepted built-in types listed in the error (blocks, parent-child, conditional-blocks, waits-for, related, discovered-from, etc.)
- Fix the empty/overlong type value in your bulk file or script variable
- Rely on the aliases "depends-on"/"blocked-by" which canonicalize to blocks
Example fix
// before bd dep add bd-1 --type "super-long-custom-dependency-type-name-exceeding-limit" --target bd-2 // after bd dep add bd-1 --type blocks --target bd-2
Defensive patterns
Strategy: validation
Validate before calling
if depType == "" || len(depType) > maxLen {
return fmt.Errorf("dependency type empty or too long")
} Prevention
- Validate bulk-file columns before running bd dep add bulk
- Only pass built-in type names; the CLI intentionally rejects custom types
- Keep type constants centralized in your tooling, not ad-hoc strings
When it happens
Trigger: `bd create ... --deps ":bd-5"` (empty type after canonicalization path), or a type string exceeding MaxDependencyTypeLen, via parseDepSpec, readBulkDepEdges, or runDepAddProxiedServer (`bd dep add --type "<very long string>"`).
Common situations: Bulk dependency files (bd dep add bulk) with a mangled first column leaving an empty type; generated scripts concatenating type names incorrectly and exceeding the length limit.
Related errors
- unknown dependency type %q; valid types: %s
- --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/e665b2da09eaa043.
Report an issue: GitHub.