gastownhall/beads · error
add label: record event: %w
Error message
add label: record event: %w
What it means
AddLabelInTx returns this when the label row inserted fine but recording the derived 'label added' aux event via InsertDerivedEvent fails. The label write and its event are meant to be atomic within the transaction, so a failed event recording aborts the operation and the caller's transaction will roll back the insert.
Source
Thrown at internal/storage/issueops/labels.go:162
if labelTable == "" {
labelTable = lt
}
if eventTable == "" {
eventTable = et
}
}
//nolint:gosec // G201: labelTable is from WispTableRouting ("labels" or "wisp_labels")
if _, err := tx.ExecContext(ctx, fmt.Sprintf(`INSERT IGNORE INTO %s (issue_id, label) VALUES (?, ?)`, labelTable), issueID, label); err != nil {
return fmt.Errorf("add label: %w", err)
}
comment := "Added label: " + label
if err := InsertDerivedEvent(ctx, tx, eventTable, AuxEvent{
IssueID: issueID,
EventType: types.EventLabelAdded,
Actor: actor,
Comment: str(comment),
}); err != nil {
return fmt.Errorf("add label: record event: %w", err)
}
// A label is part of the bead snapshot, so a label write journals as an
// update carrying the complete post-mutation set.
return RecordEventInTx(ctx, tx, EventUpdate, issueID, actor)
}
// RemoveLabelInTx removes a label from an issue and records an event within
// an existing transaction. Automatically routes to wisp tables if the ID is
// an active wisp.
//
//nolint:gosec // G201: table names come from WispTableRouting (hardcoded constants)
func RemoveLabelInTx(ctx context.Context, tx DBTX, labelTable, eventTable, issueID, label, actor string) error {
if labelTable == "" || eventTable == "" {
isWisp := IsActiveWispInTx(ctx, tx, issueID)
_, lt, et, _ := WispTableRouting(isWisp)
if labelTable == "" {
labelTable = lt
}View on GitHub (pinned to 71377f2769)
Solutions
- Run schema migrations to ensure the events table exists
- Retry the whole transaction — the atomic design means partial state is rolled back
- Inspect the wrapped InsertDerivedEvent error for constraint or connection specifics
Defensive patterns
Strategy: try-catch
Validate before calling
var exists int
_ = tx.QueryRow(`SELECT COUNT(*) FROM information_schema.tables WHERE table_name = 'events'`).Scan(&exists)
if exists == 0 { return errors.New("events table missing; run bd migrate") } Try / catch
if err := issueops.AddLabelInTx(ctx, tx, issueID, label, actor); err != nil {
if strings.Contains(err.Error(), "record event") {
// transaction will roll back the label insert; safe to retry whole tx
}
return err
} Prevention
- Keep schema migrations current for derived-event tables
- Retry whole transactions — atomicity means no partial label state persists
- Keep event comment payloads small
- Watch for mid-transaction connection errors on remote backends
When it happens
Trigger: ApplyLabelPatch → AddLabelInTx where InsertDerivedEvent fails: event table missing, event row violates constraints, or connection error after the label INSERT succeeded.
Common situations: Schema versions missing the derived-events table; oversized comment payloads; connection drops mid-transaction on remote backends.
Related errors
- get issue labels: %w
- ErrTransaction
- failed to add label %s to %s: %w
- open unit of work: %w
- failed to begin transaction: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/a13addcf9bf3a2eb.
Report an issue: GitHub.