gastownhall/beads · error
get labels from %s: %w
Error message
get labels from %s: %w
What it means
Raised when the batched label lookup in getLabelsFromTable fails to execute its query against the label table, wrapped as "get labels from <table>: <err>". IDs are chunked (queryBatchSize=200) with IN (...) placeholders, so errors come from the driver: missing table, lock, connection, or malformed placeholders/args.
Source
Thrown at internal/storage/domain/db/issue_search.go:374
}
return nil
}
//nolint:gosec // G201: labelTable is "labels" or "wisp_labels" (hardcoded by callers).
func (r *issueSQLRepositoryImpl) getLabelsFromTable(ctx context.Context, labelTable string, ids []string) (map[string][]string, error) {
result := make(map[string][]string)
for start := 0; start < len(ids); start += queryBatchSize {
end := start + queryBatchSize
if end > len(ids) {
end = len(ids)
}
placeholders, args := buildInPlaceholders(ids[start:end])
rows, err := r.runner.QueryContext(ctx, fmt.Sprintf(
`SELECT issue_id, label FROM %s WHERE issue_id IN (%s) ORDER BY issue_id, label`,
labelTable, placeholders), args...)
if err != nil {
return nil, fmt.Errorf("get labels from %s: %w", labelTable, err)
}
for rows.Next() {
var issueID, label string
if err := rows.Scan(&issueID, &label); err != nil {
_ = rows.Close()
return nil, fmt.Errorf("get labels: scan: %w", err)
}
result[issueID] = append(result[issueID], label)
}
_ = rows.Close()
if err := rows.Err(); err != nil {
return nil, fmt.Errorf("get labels: rows: %w", err)
}
}
return result, nil
}
//nolint:gosec // G201: depTable is "dependencies" or "wisp_dependencies" (hardcoded by callers).View on GitHub (pinned to 71377f2769)
Solutions
- Unwrap to identify the driver error (no such table vs locked vs too many parameters).
- Run `bd doctor` / migrations to create the label table with the expected schema.
- If hitting a parameter limit, ensure you are on a current bd version that batches IDs (200 per batch).
- Clear competing locks and retry; verify DB file permissions and disk space.
Example fix
// before // old bd version builds one giant IN(...) -> "too many SQL variables" // after upgrade bd to a version batching label lookups (queryBatchSize = 200) // or repair schema: bd doctor && bd migrate
Defensive patterns
Strategy: validation
Validate before calling
if err := bd.CheckTables(dbPath, "labels"); err != nil {
return fmt.Errorf("run `bd migrate`: %w", err)
}
if len(issueIDs) == 0 { return nil } // skip empty label lookups Type guard
func isLabelLookupError(err error) bool {
return err != nil && strings.Contains(err.Error(), "get labels from ")
} Try / catch
page, err := store.Search(ctx, q, filter)
if err != nil && isLabelLookupError(err) {
if strings.Contains(err.Error(), "too many") {
// driver parameter cap hit; upgrade bd (batched lookups) or chunk IDs
}
return fmt.Errorf("label lookup failed: %w", err)
} Prevention
- Keep bd up to date so label lookups are batched (200 IDs per query).
- Run migrations when labels tables are introduced or renamed.
- Avoid external tools inserting labels with NULL keys.
- Verify driver parameter limits when embedding a custom SQL driver.
When it happens
Trigger: Search or fetchIssuesByIDs hydration issues that have labels; the SELECT ... WHERE issue_id IN (...) fails because the label table doesn't exist, the DB is locked, the connection drops, or the batch exceeds driver limits.
Common situations: Legacy databases without the labels table; schema renamed between bd versions; extremely large ID batches against drivers with IN-clause limits (SQLite variable caps); concurrent write locks.
Related errors
- get labels for issues from %s: %w
- get issues by IDs: labels from %s: %w
- get issue labels: %w
- get labels: %w
- add label: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/a3f2baa252db18a7.
Report an issue: GitHub.