Skip to content

Monitoring bulk-action runs

Every bulk action you fire — assign, attendance, delete, send-message, edit — shows up on /bulk-actions as a row in the run history. That page is your inspection point: did the run finish, did rows fail, do you need to retry, and what exactly changed.

Bulk-action history

The page auto-polls every 5 seconds while any run is active, so you don't need to refresh.

Run states

Each row has a status badge:

StateMeaning
QueuedThe run is in the work queue but the worker hasn't started it yet. Usually milliseconds.
RunningWorker is processing rows. The progress bar shows N of M done.
CompletedAll rows applied with no failures.
PartialSome rows applied, some failed. Most actionable state — you'll usually retry.
FailedA system-level error stopped the run (database unavailable, permission revoked mid-run).
CancelledYou hit Cancel. Already-applied rows stay; pending rows skip.

Opening a run

Click any row and you'll see the run detail page:

  • Summary cards — total rows, applied, failed, skipped, duration.
  • Selection snapshot — the exact list of member IDs the run targeted, captured at click-Apply time.
  • Failed items — every row that didn't apply, with a reason.
  • Retry failed button (when failures exist).
  • Cancel button (when the run is queued or running).
  • Re-run button (when the run is finished, regardless of outcome).

The failed-items list

A row fails when the worker tries to write it and the database rejects the operation. Common reasons:

ErrorWhat it meansUsually a
permission deniedThe current user lost the permission since clicking ApplyPermission was revoked mid-run
member not foundThe member was deleted by someone else during the runRace condition
unique violationThe write would create a duplicateRe-running an old assign on members already in the target
null value violates not-nullA required field was missingAlmost always a workflow misconfiguration

The reason text appears inline next to each failed member, so you can scan the list and decide if the run is worth retrying as-is or if you need to fix the underlying problem first.

Retry-failed is idempotent

The retry button re-queues only the rows that failed, with the same parameters. Already-applied rows stay applied — the action doesn't reapply them. Safe to click as many times as you need until either every row succeeds or the failure reason changes (e.g. permission was restored).

Cancel mid-flight

For long-running actions on thousands of rows, you can Cancel from the run detail page. The worker stops fetching the next batch and the run moves to Cancelled. Already-applied rows stay applied. The selection snapshot is preserved, so you can re-run on the same list later.

Cancel is not undo

Cancelling stops further writes, but it does not roll back what's already been written. If you cancelled a delete and 200 of 500 members were already soft-deleted, those 200 stay soft-deleted. Use the recycle bin to restore them if needed.

How long is the history kept

Run rows live in bulk_action_runs and stick around for 90 days. After that, a nightly job archives them off the live table. Permanent audit of who-changed-what is in audit log, which retains indefinitely.

Notifications

If a run takes more than 30 seconds, GCM emails the user who started it when it finishes. If the run hits Partial or Failed, the email includes a link straight to the run detail page. For runs under 30 seconds you'll see the result in-page, no email.

Next steps

  1. Bulk assign & attendance — the most common bulk actions.
  2. Delete & restore — soft-delete and the 30-day window.
  3. Audit log — long-term record of what changed.
  4. Users & roles → Audit log — for tracing permission grants and revokes.