gastownhall/beads · error
count inbound dependencies from %s: %w
Error message
count inbound dependencies from %s: %w
What it means
DeleteResolvedSetInTx aborts when the query that finds inbound dependencies pointing at the batch (SELECT issue_id FROM <depTable> WHERE target IN (...)) fails. The table name is interpolated into the message. Tables marked optional are skipped when they don't exist, so this error means a non-optional dependency table query genuinely failed — connection loss, SQL error, or cancellation.
Source
Thrown at internal/storage/issueops/delete.go:255
eventsCount += wispEventsCount
for i := 0; i < len(set.All); i += deleteBatchSize {
end := i + deleteBatchSize
if end > len(set.All) {
end = len(set.All)
}
batch := set.All[i:end]
batchInClause, batchArgs := buildSQLInClause(batch)
for _, depTable := range []string{"dependencies", "wisp_dependencies"} {
rows, err := tx.QueryContext(ctx,
fmt.Sprintf(`SELECT issue_id FROM %s WHERE %s`, depTable, depTargetIn("", batchInClause)),
batchArgs...)
if err != nil {
if optionalBlockedTable(depTable) && isTableNotExistError(err) {
continue
}
return nil, fmt.Errorf("count inbound dependencies from %s: %w", depTable, err)
}
for rows.Next() {
var issID string
if err := rows.Scan(&issID); err != nil {
_ = rows.Close()
return nil, fmt.Errorf("scan inbound dependency: %w", err)
}
if !deletedSet[issID] {
depsCount++
}
}
_ = rows.Close()
if err := rows.Err(); err != nil {
return nil, fmt.Errorf("iterate inbound dependencies from %s: %w", depTable, err)
}
}
}
View on GitHub (pinned to 71377f2769)
Solutions
- Note the table name in the message and check that table's existence/integrity first.
- Unwrap the driver error for the exact SQL failure (syntax, unknown table, connection).
- Retry the delete on a fresh transaction if transient.
- If using a non-Dolt driver, confirm it supports the dependency-table SQL emitted here or route through the driver interface fix.
Example fix
// before
err := batchDelete(ctx, tx, ids)
// after
err := batchDelete(ctx, tx, ids)
if err != nil && strings.Contains(err.Error(), "dependencies") {
return fmt.Errorf("dependency table unreadable; run schema check: %w", err)
} Defensive patterns
Strategy: try-catch
Validate before calling
for _, tbl := range []string{"dependencies", "wisp_dependencies"} {
if err := checkTableExists(ctx, db, tbl); err != nil {
return fmt.Errorf("required table %s missing: %w", tbl, err)
}
} Try / catch
err := batchDelete(ctx, tx, ids)
if err != nil {
var opErr *fmt.WrapError // inspect the named table in the message
m := tableFromInboundDepError(err)
if m != "" {
return fmt.Errorf("delete aborted at dependency table %q: %w", m, err)
}
return err
} Prevention
- Use only drivers that implement the full beads driver interface (storage boundary rule).
- Test deletes against the driver in CI (see backend/conformance deleter_contract).
- Keep transactions short so connection resets are unlikely mid-scan.
When it happens
Trigger: Calling DeleteIssuesInTx/DeleteInTx where a dependency table query inside the batched dry-run scan fails: connection dropped mid-loop, invalid batch clause under a driver with different SQL quirks, or context cancellation.
Common situations: Custom/alternative storage drivers whose SQL dialect mismatches the generated IN-clause query; Dolt connection reset while scanning many batches; schema drift removing a required dependency table.
Related errors
- count wisp dependencies: %w
- count labels: %w
- count events: %w
- check remaining blockers from %s: %w
- no store is open for this workspace
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/d9885128d92c2c29.
Report an issue: GitHub.