gastownhall/beads · error
db: DependencySQLRepository.Insert: dep must not be nil
Error message
db: DependencySQLRepository.Insert: dep must not be nil
What it means
DependencySQLRepository.Insert returns this error when the dep argument is nil. It is the first of several defensive guards in Insert validating the dependency record before any SQL write. A nil dependency carries no IssueID/DependsOnID so it can never be persisted.
Source
Thrown at internal/storage/domain/db/dependency.go:73
return "depends_on_external", nil
}
var probe int
err := r.runner.QueryRowContext(ctx, "SELECT 1 FROM wisps WHERE id = ? LIMIT 1", dependsOnID).Scan(&probe)
switch {
case err == nil:
return "depends_on_wisp_id", nil
case errors.Is(err, sql.ErrNoRows):
return "depends_on_issue_id", nil
case dberrors.IsTableNotExist(err):
return "depends_on_issue_id", nil
default:
return "", fmt.Errorf("classify dep target %s: %w", dependsOnID, err)
}
}
func (r *dependencySQLRepositoryImpl) Insert(ctx context.Context, dep *types.Dependency, actor string, opts domain.DepInsertOpts) error {
if dep == nil {
return errors.New("db: DependencySQLRepository.Insert: dep must not be nil")
}
if dep.IssueID == "" {
return errors.New("db: DependencySQLRepository.Insert: IssueID must not be empty")
}
if dep.DependsOnID == "" {
return errors.New("db: DependencySQLRepository.Insert: DependsOnID must not be empty")
}
if dep.IssueID == dep.DependsOnID {
// Lead with the sentinel so this defensive repo-layer guard renders like
// every other self-dep site ("cannot add self-dependency: X cannot depend
// on itself") instead of appending the sentinel text.
return fmt.Errorf("db: DependencySQLRepository.Insert: %w: %s cannot depend on itself", domain.ErrSelfDependency, dep.IssueID)
}
metadata := dep.Metadata
if metadata == "" {
metadata = "{}"
}View on GitHub (pinned to 71377f2769)
Solutions
- Check dep != nil at the call site before invoking Insert.
- Fix the upstream construction path so a valid *types.Dependency is always built.
- If the dependency is legitimately absent, skip the Insert rather than calling it.
Example fix
// before
var dep *types.Dependency
repo.Insert(ctx, dep, actor, opts) // panics-free but errors
// after
if dep == nil {
return nil // nothing to insert
}
repo.Insert(ctx, dep, actor, opts) Defensive patterns
Strategy: validation
Validate before calling
if dep == nil {
return fmt.Errorf("dependency not initialized")
} Type guard
func depValid(d *types.Dependency) bool { return d != nil } Try / catch
if err := repo.Insert(ctx, dep, actor, opts); err != nil {
if strings.Contains(err.Error(), "dep must not be nil") {
// skip or construct dependency
}
} Prevention
- Never pass lookup results to Insert without a nil check
- Construct dependencies via a single validated constructor
- Return not-found explicitly instead of nil pointers
When it happens
Trigger: Calling Insert(ctx, nil, actor, opts) — usually from a caller that built the *types.Dependency conditionally and skipped initialization on some code path, or passed a nil pointer from a map/slice lookup.
Common situations: A lookup that returned nil, nil (not found) and the result was passed to Insert unchecked; optional dependency creation where the dep pointer was left nil.
Related errors
- db: DependencySQLRepository.Insert: IssueID must not be empt
- db: DependencySQLRepository.Insert: DependsOnID must not be
- db: DependencySQLRepository.ValidateBlockingHierarchy: dep m
- no store is open for this workspace
- not found
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/0c3038ce21f124a2.
Report an issue: GitHub.