gastownhall/beads · error
db: DependencySQLRepository.Insert: record dependency_added…
Error message
db: DependencySQLRepository.Insert: record dependency_added event: %w
What it means
This error wraps a failure from the events repository while recording the dependency_added event after a successful edge insert. The dependency was created, but writing its history entry to the source issue's event table failed, so the emit path aborts with this wrap.
Solutions
- Check that the events table exists and matches the current schema (bd migrate).
- Verify write connectivity; retry the operation.
- If the event is non-essential for your flow, call Insert with EmitEvent=false to skip event recording.
- Inspect the wrapped driver error for the underlying cause.
Defensive patterns
Strategy: try-catch
Try / catch
if err := repo.Insert(ctx, dep, actor, opts); err != nil {
if strings.Contains(err.Error(), "record dependency_added event") {
// edge may exist; check before retrying; consider EmitEvent=false if audit not needed
}
} Prevention
- Keep the events table migrated to current schema.
- Set EmitEvent=false for structural/implicit edges that do not need history.
- Write to a primary, not a read-only replica.
When it happens
Trigger: Calling Insert with opts.EmitEvent=true where events.Record fails — event table missing, connection failure, or constraint error writing the Event row for dep.IssueID.
Common situations: Older database lacking the events table or expected columns; read-only replica receiving the write; DB connection dropped between dep insert and event record.
Related errors
- add label: record event
- db: DependencySQLRepository.Delete: record…
- db: EventsSQLRepository.CountAllForIDs
- db: EventsSQLRepository.DeleteAllForIDs from
- db: EventsSQLRepository.DeleteAllForIDs rows affected
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/c50c70a2102bd205.
Report an issue: GitHub.
Appendix: source
Thrown at internal/storage/domain/db/dependency.go:185
// Record the dependency_added event on the source's event table, matching the
// embedded/issueops AddDependencyInTx path so the bd CLI and library callers
// observe the same history from either write plumbing. Reached only on the
// genuine new-edge path; the idempotent same-type refresh returned earlier.
// Gated on EmitEvent so only the explicit dep verbs emit: create-with-deps
// and reparent call Insert directly without it, so an implicit parent-child /
// --deps / waits-for edge produces no event. The embedded structural paths
// (createIssueWithDeps, reparent) match this by calling the plain,
// no-event AddDependency/tx.AddDependency, whose issueops.AddDependencyInTx
// EmitEvent gate is likewise unset — so both backends stay silent on implicit
// edges and emit only for the explicit bd dep add / bd link verbs.
if opts.EmitEvent {
if err := r.events.Record(ctx, domain.Event{
IssueID: dep.IssueID,
Type: types.EventDependencyAdded,
Actor: actor,
NewValue: fmt.Sprintf("Added dependency: %s %s %s", dep.IssueID, dep.Type, dep.DependsOnID),
}, domain.RecordEventOpts{UseWispsTable: opts.UseWispsTable}); err != nil {
return fmt.Errorf("db: DependencySQLRepository.Insert: record dependency_added event: %w", err)
}
}
// is_blocked maintenance mirrors the classic AddDependencyInTx flow
// (issueops/dependencies.go): the affected set expands the source by its
// parent-child descendants (plus, for parent-child edges, waiters on the
// target spawner), then a Mark pass propagates blocked state — or, for
// parent-child adds (not monotonic: an already-closed child can satisfy an
// any-children waits-for gate), a full mark/unmark Recompute. Skipping the
// expansion left descendants stale when a blocking edge landed on their
// ancestor (bd-6dnrw.44 item 3).
srcIsWisp := opts.UseWispsTable
var affectedIssues, affectedWisps []string
var aerr error
if srcIsWisp {
affectedIssues, affectedWisps, aerr = issueops.AffectedByDepChangeForWispInTx(ctx, r.runner, dep.IssueID, dep.DependsOnID, dep.Type)
} else {
affectedIssues, affectedWisps, aerr = issueops.AffectedByDepChangeInTx(ctx, r.runner, dep.IssueID, dep.DependsOnID, dep.Type)View on GitHub (pinned to 71377f2769)