gastownhall/beads · error

get comments from %s: %w

Error message

get comments from %s: %w

What it means

getCommentsForIDsInto batches a SELECT of comments from the comments (or wisp_comments) table for a set of issue IDs and wraps any driver-level query failure with "get comments from <table>:". This fires when the SQL statement itself fails to execute — bad SQL, missing table, or a driver/transaction-level error.

Source

Thrown at internal/storage/issueops/bulk_ops.go:152

func getCommentsForIDsInto(ctx context.Context, tx *sql.Tx, table string, ids []string, result map[string][]*types.Comment) error {
	for start := 0; start < len(ids); start += queryBatchSize {
		end := start + queryBatchSize
		if end > len(ids) {
			end = len(ids)
		}
		batch := ids[start:end]
		placeholders, args := buildSQLInClause(batch)

		query := fmt.Sprintf(`
			SELECT id, issue_id, author, text, created_at
			FROM %s
			WHERE issue_id IN (%s)
			ORDER BY issue_id, created_at ASC, id ASC
		`, table, placeholders)

		rows, err := tx.QueryContext(ctx, query, args...)
		if err != nil {
			return fmt.Errorf("get comments from %s: %w", table, err)
		}

		for rows.Next() {
			var c types.Comment
			if err := rows.Scan(&c.ID, &c.IssueID, &c.Author, &c.Text, &c.CreatedAt); err != nil {
				_ = rows.Close()
				return fmt.Errorf("scan comment: %w", err)
			}
			result[c.IssueID] = append(result[c.IssueID], &c)
		}
		if err := rows.Err(); err != nil {
			_ = rows.Close()
			return err
		}
		_ = rows.Close()
	}
	return nil
}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Verify the DB schema is current (run the tool's migration/upgrade path) so comments and wisp_comments exist
  2. Inspect the wrapped driver error for the root cause (no such table vs context canceled vs busy)
  3. Ensure the *sql.Tx passed in is still valid and uncommitted/unrolled-back when this runs
  4. Increase the context timeout or retry the whole transaction if it was a transient busy/lock error

Example fix

// before: reusing an aborted tx
rows, err := tx.QueryContext(ctx, query, args...) // fails: transaction has been rolled back
// after: check tx state / use a fresh transaction
tx, err := db.BeginTx(ctx, nil)
if err != nil { return nil, err }
rows, err := tx.QueryContext(ctx, query, args...)
Defensive patterns

Strategy: try-catch

Validate before calling

// Go has no pre-call validation; ensure schema and tx health before the call
if tx == nil { return errors.New("nil transaction") }
// optionally: verify table exists via a lightweight query before bulk reads

Type guard

// errors.As to extract the driver error
var driverErr *sqlite.Error
if errors.As(err, &driverErr) { /* inspect driverErr.Code */ }

Try / catch

err := GetCommentsForIssuesInTx(ctx, tx, ids)
if err != nil {
    var derr interface{ Error() string }
    if errors.Is(err, context.DeadlineExceeded) { /* retry whole tx */ }
    return fmt.Errorf("bulk comment fetch failed: %w", err)
}

Prevention

When it happens

Trigger: tx.QueryContext fails on the comments/wisp_comments table: table missing (schema not migrated), SQLite/dolt driver error, transaction already aborted or rolled back by a prior step, or context canceled mid-query.

Common situations: Running bd against a database created by an older version that lacks the wisp_comments table; a rolled-back or timed-out transaction reused by the caller; context deadline exceeded during a large bulk comment read.

Understand the failure class

Background: "query failed", "%w: SQL error" — wrapped database query errors in Go libraries explained — this error's family across 3 libraries.

Related errors


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