gastownhall/beads · error
scan same-content events in %s: %w
Error message
scan same-content events in %s: %w
What it means
In InsertDerivedEventReturningID, a dedup lookup selects ids of existing same-content events; this wraps the QueryContext failure itself (before any rows are read). The query uses `<=>` (NULL-safe equality) against the derived events table routed by `table`; any SQL-level error — bad table name, missing column, connection failure — surfaces here.
Source
Thrown at internal/storage/issueops/derivedid.go:137
for _, p := range []*sql.NullString{&e.OldValue, &e.NewValue, &e.Comment} {
if !p.Valid {
*p = str("")
}
}
}
digest := rowid.Digest([]sql.NullString{
str(e.IssueID), str(string(e.EventType)), str(e.Actor),
e.OldValue, e.NewValue, e.Comment, str(e.CreatedAt),
})
taken := make(map[string]bool)
rows, err := tx.QueryContext(ctx, fmt.Sprintf(`
SELECT id FROM %s
WHERE issue_id = ? AND event_type = ? AND actor = ?
AND old_value <=> ? AND new_value <=> ? AND comment <=> ?
AND created_at = ?`, table),
e.IssueID, string(e.EventType), e.Actor, e.OldValue, e.NewValue, e.Comment, e.CreatedAt)
if err != nil {
return "", fmt.Errorf("scan same-content events in %s: %w", table, err)
}
for rows.Next() {
var id string
if err := rows.Scan(&id); err != nil {
_ = rows.Close()
return "", fmt.Errorf("scan same-content events in %s: %w", table, err)
}
taken[id] = true
}
_ = rows.Close()
if err := rows.Err(); err != nil {
return "", fmt.Errorf("scan same-content events in %s: %w", table, err)
}
id := firstFreeDerivedID(table, digest, taken)
if _, err := tx.ExecContext(ctx, fmt.Sprintf(`
INSERT INTO %s (id, issue_id, event_type, actor, old_value, new_value, comment, created_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, table),View on GitHub (pinned to 71377f2769)
Solutions
- Run schema migrations so the events table has all expected columns.
- Verify the table routing constant matches an existing derived events table.
- Check tx health / connection state; retry outside the failed transaction if it's aborted.
- Inspect the wrapped driver error (`%w` chain) for the precise SQL failure (e.g. 'Unknown column').
Example fix
// before: column missing on old schema
_, err := tx.QueryContext(ctx, fmt.Sprintf(`SELECT id FROM %s WHERE ... AND comment <=> ?`, table), ...)
// after: migrate first, e.g. `bd migrate` / ensure ALTER TABLE applied before use
if err := migrate(ctx, db); err != nil { return err }
_, err := tx.QueryContext(ctx, fmt.Sprintf(`SELECT id FROM %s WHERE ... AND comment <=> ?`, table), ...) Defensive patterns
Strategy: try-catch
Validate before calling
if err := ctx.Err(); err != nil { return err }
cols, err := tableColumns(tx, table)
if err != nil { return err }
for _, c := range []string{"id", "issue_id", "event_type", "actor", "old_value", "new_value", "comment", "created_at"} {
if !slices.Contains(cols, c) {
return fmt.Errorf("events table %s missing column %s; migrate first", table, c)
}
} Type guard
func isQueryErr(err error) bool {
var me *mysql.MySQLError // dolt speaks mysql protocol
return errors.As(err, &me)
} Try / catch
id, err := InsertDerivedEvent(ctx, tx, e)
if err != nil {
if strings.Contains(err.Error(), "Unknown column") || strings.Contains(err.Error(), "doesn't exist") {
return fmt.Errorf("schema drift on %s; run migrations: %w", table, err)
}
return err
} Prevention
- Apply all migrations before importing or commenting via derived-event APIs.
- Only pass the library's documented table routing constants.
- Check transaction health after long operations; don't reuse aborted txs.
- Log the unwrapped driver error chain for diagnostics.
When it happens
Trigger: Calling AddCommentEventInTx or InsertDerivedEvent against a table missing the expected columns (id, issue_id, event_type, actor, old_value, new_value, comment, created_at), or with a dead/cancelled connection or wrong `table` routing constant.
Common situations: Older databases lacking newer event-table columns; passing an unsupported table constant; Dolt connection dropped inside a long transaction.
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
- record event in %s: %w
- read newest comment time from %s: %w
- check comment existence in %s: %w
- iter issues: query: %w
- resolve existing wisps for batch delete: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/2ca3adaaf829d257.
Report an issue: GitHub.