gastownhall/beads · error
failed to get issue from %s: %w
Error message
failed to get issue from %s: %w
What it means
Returned by scanIssueFromTable when scanIssueFrom fails for a reason other than sql.ErrNoRows — i.e., the row was fetched but could not be scanned into the issue struct, or the query itself errored. The message includes the table name and wraps the underlying driver/scan error. Unlike the ErrNoRows case this indicates a genuine unexpected failure reading the issue.
Source
Thrown at internal/storage/dolt/wisps.go:40
return issueops.InsertIssueIntoTable(ctx, tx, table, issue)
}
// scanIssueFromTable scans a single issue from the specified table.
//
//nolint:gosec // G201: table is a hardcoded constant ("issues" or "wisps")
func scanIssueFromTable(ctx context.Context, db *sql.DB, table, id string) (*types.Issue, error) {
row := db.QueryRowContext(ctx, fmt.Sprintf(`
SELECT %s
FROM %s %s
WHERE id = ?
`, issueSelectColumns, table, sqlbuild.LeaseJoin(table)), id)
issue, err := scanIssueFrom(row)
if err == sql.ErrNoRows {
return nil, fmt.Errorf("%w: issue %s", storage.ErrNotFound, id)
}
if err != nil {
return nil, fmt.Errorf("failed to get issue from %s: %w", table, err)
}
return issue, nil
}
// generateIssueIDInTable generates a unique ID, checking for collisions
// in the specified table. Supports counter mode for non-ephemeral issues.
//
//nolint:gosec // G201: table is a hardcoded constant
func generateIssueIDInTable(ctx context.Context, tx *sql.Tx, table, prefix string, issue *types.Issue, actor string) (string, error) {
// Counter mode only applies to the issues table (not wisps).
if table == "issues" {
counterMode, err := isCounterModeTx(ctx, tx)
if err != nil {
return "", err
}
if counterMode {
return nextCounterIDTx(ctx, tx, prefix)
}View on GitHub (pinned to 71377f2769)
Solutions
- Read the wrapped cause (%w) to see the exact scan/driver error
- Confirm the table schema matches the binary's expected columns (issueSelectColumns); run any available schema migration (e.g. bd doctor / migrate)
- Upgrade or downgrade bd so binary and database schema versions agree
- If a row is corrupt, restore from Dolt history or re-export/import the issue
Example fix
// before // binary expects a column the DB lacks: scan fails with 'failed to get issue from wisps: ...' // after // run: bd doctor (or the project's migrate step) to align schema, then retry the lookup
Defensive patterns
Strategy: try-catch
Validate before calling
// check schema alignment before lookups
rows, err := db.Query(`SHOW COLUMNS FROM wisps`)
if err != nil {
return fmt.Errorf("wisps table missing or unreadable: %w", err)
}
// compare against expected columns / run bd doctor Try / catch
issue, err := store.GetIssue(ctx, id)
if err != nil {
var msg string
if !errors.Is(err, storage.ErrNotFound) && strings.Contains(err.Error(), "failed to get issue from") {
return fmt.Errorf("schema/driver problem reading issue: %w", err)
}
return err
} Prevention
- Run bd doctor / migrations after every binary upgrade
- Keep binary and database schema versions in sync
- Back up via Dolt history before schema-affecting operations
- Treat non-ErrNoRows scan failures as schema or corruption signals, and investigate the wrapped cause
When it happens
Trigger: A SELECT from the wisps/issues table by ID succeeds in returning a row but scanIssueFrom fails: column/type mismatch after a schema change, NULL in a non-nullable-scanned column, or an underlying driver error during Scan/QueryRowContext.
Common situations: Running a newer bd binary against an older database (or vice versa) so issueSelectColumns doesn't match the actual table schema; corrupted rows; Dolt/driver version upgrades changing type mapping.
Related errors
- ErrScan
- failed to recompute is_blocked: %w
- failed to scan federation peer: %w
- failed to scan comment: %w
- failed to get wisp labels: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/67d7512e9289eb09.
Report an issue: GitHub.