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

  1. Note the table name in the message and check that table's existence/integrity first.
  2. Unwrap the driver error for the exact SQL failure (syntax, unknown table, connection).
  3. Retry the delete on a fresh transaction if transient.
  4. 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

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


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/d9885128d92c2c29. Report an issue: GitHub.