{"record":{"id":"670c4cffd57ab7fc","repo":"gastownhall/beads","slug":"record-wake-event-for-s-w","errorCode":null,"errorMessage":"record wake event for %s: %w","messagePattern":"record wake event for (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/issueops/wake_defers.go","lineNumber":133,"sourceCode":"\t\tres, err := tx.ExecContext(ctx, fmt.Sprintf(`\n\t\t\tUPDATE %s\n\t\t\tSET status = 'open', defer_until = NULL, updated_at = ?, row_lock = ?\n\t\t\tWHERE id = ? AND status = 'deferred' AND defer_until IS NOT NULL\n\t\t\t  AND defer_until <= UTC_TIMESTAMP()\n\t\t`, table), now, freshRowLock(), id)\n\t\tif err != nil {\n\t\t\treturn woken, fmt.Errorf(\"wake expired defer %s: %w\", id, err)\n\t\t}\n\t\tn, err := res.RowsAffected()\n\t\tif err != nil {\n\t\t\treturn woken, fmt.Errorf(\"wake expired defer %s rows affected: %w\", id, err)\n\t\t}\n\t\tif n == 0 {\n\t\t\tcontinue // rescued concurrently — leave it be\n\t\t}\n\t\tif err := RecordFullEventInTable(ctx, tx, eventsTable, id, types.EventStatusChanged,\n\t\t\tDeferWakeActor, string(types.StatusDeferred), string(types.StatusOpen)); err != nil {\n\t\t\treturn woken, fmt.Errorf(\"record wake event for %s: %w\", id, err)\n\t\t}\n\t\t// A wake is a status change, so it journals as an update. Emitted past\n\t\t// the rows-affected re-check, so a concurrently-rescued bead records\n\t\t// nothing.\n\t\tif err := RecordEventInTx(ctx, tx, EventUpdate, id, DeferWakeActor); err != nil {\n\t\t\treturn woken, err\n\t\t}\n\t\twoken = append(woken, id)\n\t}\n\treturn woken, nil\n}\n","sourceCodeStart":115,"sourceCodeEnd":145,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/issueops/wake_defers.go#L115-L145","documentation":"Thrown when RecordFullEventInTable fails while journaling the deferred→open status-change event for a freshly woken issue. The row was already updated to 'open' in the same transaction, so this error leaves a woken bead without its status-change history entry; the whole transaction aborts via the returned error.","triggerScenarios":"Calling WakeExpiredDefersInTx when inserting into the events table fails: missing/wrong events table name, schema mismatch in the events columns, connection failure, or constraint violation inside the transaction.","commonSituations":"Events table not created by migration; mismatched events-table parameter (issues table passed where events table expected); disk-full or duplicated-event constraint on the backend.","solutions":["Inspect the wrapped cause and verify the events table exists with the expected schema.","Confirm the correct events table name is passed to WakeExpiredDefersInTx (not the issues table).","Run storage migrations so the events table matches the current beads version.","Retry after fixing — the transaction rolls back atomically so no partial state persists."],"exampleFix":"// before: wrong table argument\nWakeExpiredDefersInTx(ctx, tx, \"issues\", \"issues\", now)\n// after\nWakeExpiredDefersInTx(ctx, tx, \"issues\", \"issue_events\", now)","handlingStrategy":"validation","validationCode":"var exists string\nerr := db.QueryRow(\"SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_NAME='issue_events'\").Scan(&exists)\nif err != nil { return errors.New(\"issue_events table missing: run beads migration\") }","typeGuard":null,"tryCatchPattern":"if err != nil {\n    return fmt.Errorf(\"wake transaction rolled back; issue %s remains deferred: %w\", id, err)\n    // atomicity guarantees no half-woken state; fix events table and retry\n}","preventionTips":["Run migrations so the events table always matches the code version.","Pass the correct events table name (not the issues table) to wake APIs.","Check disk space and constraint definitions on the events table.","Trust transaction rollback: retry after fixing the cause leaves no partial state."],"tags":["database","event-journal","insert-failed"],"backgroundTag":"event-record-insert-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}