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
- Verify the DB schema is current (run the tool's migration/upgrade path) so comments and wisp_comments exist
- Inspect the wrapped driver error for the root cause (no such table vs context canceled vs busy)
- Ensure the *sql.Tx passed in is still valid and uncommitted/unrolled-back when this runs
- 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
- Keep the database schema migrated to the current version
- Always pass a live, uncommitted transaction and a context with adequate timeout
- Retry full transactions on transient busy/locked errors instead of partial retries
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
- failed to query cross-table duplicates: %w
- query cross-table duplicates: %w
- query issues: %w
- list remotes: %w
- ErrTransaction
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/495f36fcf6a1081b.
Report an issue: GitHub.