escaping_side_effects
Find Django transaction.atomic blocks containing side effects like emails, webhooks, or tasks that won't roll back; identify calls needing on_commit to prevent race conditions and data loss.
Instructions
Calls inside a transaction whose effect cannot be rolled back.
A transaction can be rolled back. An email cannot, and neither can a
webhook or a task a worker has already picked up.
with transaction.atomic():
order = Order.objects.create(...)
send_confirmation.delay(order.pk)
Two defects, and only one is famous. The race: the broker has the task
immediately, a worker can start before the commit, and it queries for a row
that is not there. It passes every test, because tests run in a transaction
that never commits with a worker that runs eagerly, and it fails under load.
The quieter one: if anything after that line raises, the order is gone and
the customer has the email.
The fix is transaction.on_commit, and calls already deferred that way are
not reported. The ecosystem's answer to this is runtime wrappers; ruff and
flake8-django do not look at it.
Args:
search_path: directory to scan. Defaults to the project root.
include_low_confidence: also report calls like `.send()` that are
guessed from the name, since it is also Signal.send and socket.send.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| search_path | No | ||
| include_low_confidence | No |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||