gastownhall/beads · error

db: DependencySQLRepository.Insert: %w

Error message

db: DependencySQLRepository.Insert: %w

What it means

This error wraps a failure from pickDepTargetColumn inside DependencySQLRepository.Insert. Before inserting a dependency edge, the repository probes the wisps table to classify the target as local issue, wisp, or external; if that probe query itself fails (not just returns no rows), the insert is aborted and the driver error is wrapped with this prefix.

Source

Thrown at internal/storage/domain/db/dependency.go:142

			}
			// A same-type add refreshes edge metadata. It is an observable graph
			// mutation, so emit the complete replacement edge for replay.
			return issueops.RecordDepEventInTx(ctx, r.runner, issueops.EventDepAdd, dep.IssueID, string(dep.Type), dep.DependsOnID, metadata, actor)
		}
		return &domain.DependencyTypeConflictError{
			IssueID:       dep.IssueID,
			DependsOnID:   dep.DependsOnID,
			ExistingType:  existingType,
			RequestedType: string(dep.Type),
		}
	case errors.Is(err, sql.ErrNoRows):
	default:
		return fmt.Errorf("db: DependencySQLRepository.Insert: check existing: %w", err)
	}

	targetCol, err := r.pickDepTargetColumn(ctx, dep.IssueID, dep.DependsOnID)
	if err != nil {
		return fmt.Errorf("db: DependencySQLRepository.Insert: %w", err)
	}

	// Deterministic id keyed on (issue_id, target), the same derivation as the
	// embedded/issueops path, so server-mode (use-case) dependency creation stays
	// merge-safe across clones and works once the DEFAULT (UUID()) is dropped (#4259).
	//nolint:gosec // G201: table is one of two hardcoded constants; targetCol is from pickDepTargetColumn
	if _, err := r.runner.ExecContext(ctx, fmt.Sprintf(`
		INSERT INTO %s (id, issue_id, %s, type, created_at, created_by, metadata, thread_id)
		VALUES (?, ?, ?, ?, ?, ?, ?, ?)
	`, table, targetCol),
		depid.New(dep.IssueID, dep.DependsOnID), dep.IssueID, dep.DependsOnID, string(dep.Type),
		time.Now().UTC(), actor, metadata, dep.ThreadID,
	); err != nil {
		if missing := r.classifyMissingEndpoint(ctx, dep, opts.UseWispsTable, targetCol, err); missing != nil {
			return missing
		}
		return fmt.Errorf("db: DependencySQLRepository.Insert: %w", err)
	}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Check database connectivity and retry the operation (transient driver failures).
  2. Verify the wisps table exists and the current user has SELECT permission on it.
  3. Run bd doctor or a DB integrity check to rule out corruption.
  4. Inspect the wrapped driver error (errors.Unwrap) for the underlying SQL cause.
Defensive patterns

Strategy: retry

Validate before calling

// ensure the target id is non-empty and syntactically valid before Insert
if dep.DependsOnID == "" || dep.IssueID == "" {
    return fmt.Errorf("dependency endpoints must be non-empty")
}

Try / catch

if err := repo.Insert(ctx, dep, actor, opts); err != nil {
    if strings.Contains(err.Error(), "classify dep target") {
        // DB probe failure: retry with backoff or check DB health
    }
}

Prevention

When it happens

Trigger: Calling Insert with a dependency whose target classification probe ('SELECT 1 FROM wisps WHERE id = ?') fails with a driver error other than ErrNoRows or table-not-exist — e.g. corrupted DB, connection failure, or permission error on the wisps table during the probe.

Common situations: Database connectivity dropped mid-transaction; wisps table locked or corrupted; running against a Dolt server with revoked SELECT privileges on wisps; transient network failure to the SQL backend.

Related errors


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