gastownhall/beads · error
get issue labels: %w
Error message
get issue labels: %w
What it means
This error wraps a failure from GetLabelsInTx while loading an issue's labels inside the same transaction used to fetch the issue row. The issue row itself was read successfully, but the subsequent label lookup against the label table failed, so the whole getIssueFromTableInTx call aborts with no partial data returned. It exists to preserve context ('which step of issue load failed') while retaining the underlying driver error via %w.
Source
Thrown at internal/storage/issueops/get_issue.go:61
return optionalBlockedTable(issueTable) && dberrors.IsMissingTable(err, issueTable)
}
func getIssueFromTableInTx(ctx context.Context, tx DBTX, issueTable, labelTable, id string) (*types.Issue, error) {
//nolint:gosec // G201: issueTable is a hardcoded literal supplied by GetIssueInTx ("issues" or "wisps")
row := tx.QueryRowContext(ctx, fmt.Sprintf(`SELECT %s FROM %s %s WHERE id = ?`,
IssueSelectColumns, issueTable, sqlbuild.LeaseJoin(issueTable)), id)
issue, err := ScanIssueFrom(row)
if err == sql.ErrNoRows || missingOptionalIssueTable(err, issueTable) {
return nil, storage.ErrNotFound
}
if err != nil {
return nil, fmt.Errorf("get issue: %w", err)
}
// Fetch labels in the same transaction to avoid MaxOpenConns=1 deadlock.
labels, err := GetLabelsInTx(ctx, tx, labelTable, id)
if err != nil {
return nil, fmt.Errorf("get issue labels: %w", err)
}
issue.Labels = labels
return issue, nil
}
View on GitHub (pinned to 71377f2769)
Solutions
- Check the wrapped cause (errors.Unwrap / %v chain) to see the real driver error from GetLabelsInTx
- Verify the label table exists and matches the current schema (run bd migration/doctor checks)
- Check for connection pool starvation: ensure the same tx is used for labels (it already is) and no external long transaction holds locks
- Retry the operation; if transient lock timeouts persist, check for other processes holding the DB
Example fix
// before
labels, err := GetLabelsInTx(ctx, tx, labelTable, id)
if err != nil {
return nil, fmt.Errorf("get issue labels: %w", err)
}
// after
labels, err := GetLabelsInTx(ctx, tx, labelTable, id)
if err != nil {
return nil, fmt.Errorf("get issue labels for %s: %w", id, err) // include issue id for debugging
} Defensive patterns
Strategy: try-catch
Validate before calling
// before calling GetIssueInTx, verify DB reachability and schema
if err := db.PingContext(ctx); err != nil {
return fmt.Errorf("database unreachable: %w", err)
}
var n int
if err := db.QueryRowContext(ctx, `SELECT COUNT(*) FROM issue_labels LIMIT 1`).Scan(&n); err != nil {
return fmt.Errorf("label table missing or unreadable: %w", err)
} Try / catch
issue, err := GetIssueInTx(ctx, tx, id)
if err != nil {
if errors.Is(err, context.DeadlineExceeded) {
// retry with fresh context / longer timeout
}
var derr *driver.Error
if errors.As(err, &derr) {
log.Printf("label fetch driver error: %v", derr)
}
return fmt.Errorf("load issue %s: %w", id, err)
} Prevention
- Keep all reads for one issue on the same transaction (the code already does this to avoid MaxOpenConns=1 deadlocks)
- Run schema migrations before upgrades so label tables match code expectations
- Set sane context timeouts for batch reads
- Avoid long-running external transactions that hold locks on the labels table
When it happens
Trigger: Calling GetIssueInTx or getJournalIssueInTx when the labels table is missing/corrupted, the transaction has been invalidated by a prior error or context cancellation, the underlying SQL query in GetLabelsInTx fails (syntax/lock timeout/connection drop), or the tx handle is dead due to the MaxOpenConns=1 pool being starved.
Common situations: Schema drift after upgrading beads where label tables weren't migrated; database locked by another long-running transaction (common with Dolt/SQLite embedded mode); context deadline exceeded during large batch reads; corrupted database file.
Related errors
- failed to begin transaction: %w
- failed to commit is_blocked repairs: %w
- get labels from %s: %w
- failed to close issue: %w
- failed to check issue existence: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/295d7b97b21a7ae3.
Report an issue: GitHub.