gastownhall/beads · error · storage.ErrValidation
%w: read edges type %d is not a usable dependency type (non-
Error message
%w: read edges type %d is not a usable dependency type (non-empty, max %d chars)
What it means
ValidateEdgeReadRequest rejects an EdgeReadRequest whose Types slice contains a dependency type that fails types.DependencyType.IsValid() — empty or exceeding types.MaxDependencyTypeLen. Such a type would act as a filter silently matching no edges, so it is refused instead. The error wraps storage.ErrValidation.
Source
Thrown at internal/storage/issueops/edges.go:27
"github.com/steveyegge/beads/internal/storage"
"github.com/steveyegge/beads/internal/types"
publicops "github.com/steveyegge/beads/issueops"
)
// ValidateEdgeReadRequest applies the request rules every EdgeReader
// implementation shares. Both tell a caller's mistake from a legitimately empty
// answer: an empty ID entry names nothing, and an unusable dependency type would
// become a filter that silently matches nothing. An empty ID SLICE is neither —
// it asks about no anchors and gets none back.
func ValidateEdgeReadRequest(request publicops.EdgeReadRequest) error {
for i, id := range request.IDs {
if id == "" {
return fmt.Errorf("%w: read edges id %d is empty", storage.ErrValidation, i)
}
}
for i, depType := range request.Types {
if !depType.IsValid() {
return fmt.Errorf("%w: read edges type %d is not a usable dependency type (non-empty, max %d chars)",
storage.ErrValidation, i, types.MaxDependencyTypeLen)
}
}
return nil
}
// EdgeReadAnchors is the de-duplicated anchor list a read runs against: the
// request's ids with repeats collapsed onto their first mention.
//
// It is shared rather than a loop in each implementation because the
// de-duplication decides the SHAPE of the answer — one entry per distinct id, in
// first-mention order. BlockingAnnotator makes the same promise over the same
// shape of request (blocking_annotation.go) and reaches it here too.
func EdgeReadAnchors(ids []string) []string {
seen := make(map[string]struct{}, len(ids))
out := make([]string, 0, len(ids))
for _, id := range ids {
if _, dup := seen[id]; dup {View on GitHub (pinned to 71377f2769)
Solutions
- Call types.DependencyType.IsValid() on each filter before building the request.
- Trim whitespace and enforce MaxDependencyTypeLen at the input boundary.
- Use the exported dependency-type constants instead of ad-hoc strings.
- Update callers to current type names after upgrades.
Example fix
// before
req := publicops.EdgeReadRequest{IDs: ids, Types: []types.DependencyType{t}}
// after
if !t.IsValid() { return fmt.Errorf("bad dependency type %q", t) }
req := publicops.EdgeReadRequest{IDs: ids, Types: []types.DependencyType{t}} Defensive patterns
Strategy: validation
Validate before calling
func validTypes(ts []types.DependencyType) bool {
for _, t := range ts { if !t.IsValid() { return false } }
return true
} Type guard
func filterValidTypes(ts []types.DependencyType) []types.DependencyType {
return slices.DeleteFunc(slices.Clone(ts), func(t types.DependencyType) bool { return !t.IsValid() })
} Try / catch
if err := ValidateEdgeReadRequest(req); err != nil {
if errors.Is(err, storage.ErrValidation) && strings.Contains(err.Error(), "dependency type") {
req.Types = filterValidTypes(req.Types)
}
} Prevention
- Run DependencyType.IsValid() on filters before the call
- Trim and length-check type strings at input
- Prefer exported type constants
- Update configs after type renames between versions
When it happens
Trigger: ReadEdges / ExecuteEdgeRead called with Types containing "" or an over-long string; types.DependencyType built from raw user input or config values without validation.
Common situations: Typo'd or renamed dependency types in flags/config; a type with trailing whitespace exceeding the length limit; older code using a type name removed or shortened in a newer beads release.
Related errors
- edge %d: invalid dependency type %q
- %w: add dependencies edge %d requires a dependency type (max
- %w: count edges type %d is not a usable dependency type (non
- %w: read edges id %d is empty
- no store is open for this workspace
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/d40c08f6e3eae6bd.
Report an issue: GitHub.