The issue involves a clear bug with a straightforward fix and testable behavior.
The `before_rename` hook fires twice when a rename operation is enqueued, causing side effects to execute multiple times. The fix involves skipping validation in the background job since it already ran synchronously before queuing. The issue is well-documented and testable.
When update_document_title is called with enqueue=True and the scheduler
is active, the before_rename controller hook is called twice:
update_document_title itself — to get the transformed name
for pre-validation before queuingrename_doc when the background job executes — because
rename_doc calls old_doc.run_method("before_rename", ...) with
validate=True (the default)Any before_rename implementation with side effects — sending emails,
writing to external services, updating related records — will execute twice.
Output of bench version
frappe 15.x.x (or develop branch)
before_rename hook that has a visible
side effect (e.g. creates a log entry, sends an email, increments a counter)update_document_title with enqueue=True on a document of that DocTypebefore_rename side effect occurs twice — once immediately and once
after the background job completes.
before_rename should fire exactly once per rename operation.
No exception — this is a silent double-execution bug.
Call chain when enqueue=True:
update_document_title
└── doc.run_method("before_rename", ...) ← 1st call
└── validate_rename(..., save_point=True)
└── doc.queue_action("rename", ...)
└── [background] execute_action
└── doc.rename()
└── rename_doc(validate=True)
└── old_doc.run_method("before_rename", ...) ← 2nd call
Fix — skip validation (and therefore before_rename) in the background job
since it already ran synchronously before queuing:
# In update_docu
Claim this issue to let others know you're working on it. You'll earn 10 points when you complete it!