From ChatGPT: -
Good — that’s a situation that comes up fairly often in custom ERPNext deployments, especially when you’re using webhooks that depend on a document’s status change.
Let’s troubleshoot this step by step, with ERPNext v15 and Docker context in mind.
1. Verify the Webhook’s Event Configuration
You said:
The webhook is configured for on_update and fires when status = “Accepted”.
That preview only tests your condition, not the actual event firing.
So we must confirm that the correct event (on_update) actually runs in your scenario.
ERPNext webhooks are triggered through the function:
frappe.integrations.doctype.webhook.webhook.trigger_webhooks(doc, method)
and are called from Frappe’s document hooks like:
-
on_update
-
after_insert
-
on_submit
-
on_cancel
So check the event type in your Webhook record:
- If you’re updating Application Status through a workflow or UI, the method triggered might not be
on_update, but rather on_change or even validate (depending on how that Doctype saves status transitions).
2. How ERPNext Handles “Status Change” Updates
In Doctypes like Job Applicant or Job Application, changing the status to “Accepted” usually triggers code in the HR module’s Python controller, not a direct on_update.
-
That controller may return early or may not call save() again if the workflow handles it internally.
-
In such cases, on_update might not fire because Frappe doesn’t re-save the document.
Test:
-
Open the console:
bench console
-
Run manually:
doc = frappe.get_doc("Job Applicant", "APP-0001")
doc.status = "Accepted"
doc.save()
Then check if your webhook fires (you can tail the logs for backend container).
If it fires here, then the issue is workflow or UI update path not triggering on_update.
3. Check Logs for Webhook Activity
Inside your backend container:
docker compose logs -f backend | grep webhook
or:
docker compose logs backend | grep -i accepted
If the webhook doesn’t even appear there, it means the event never reached the trigger function.
If you see something like “Error while firing webhook,” it’s a different issue (e.g., request failure).
4. Verify the Condition Expression
In the Webhook configuration, make sure:
-
Condition field uses correct syntax:
doc.status == "Accepted"
-
Double quotes vs single quotes matter.
-
You can test it in bench console:
doc = frappe.get_doc("Job Applicant", "APP-0001")
eval('doc.status == "Accepted"', {}, {"doc": doc})
If that returns True, condition is valid.
5. Alternative (More Reliable) Hook Event: after_save
Try changing the webhook event from on_update to after_save.
This fires consistently after any save (even workflow-triggered ones).
You can test it by:
-
Changing event type to after_save
-
Keeping the condition same (doc.status == "Accepted")
-
Save and re-test the status update.
after_save is safer for workflow-driven status changes.
6. Confirm Webhook is Enabled
Obvious but often missed:
-
The “Enabled” checkbox on the Webhook must be ticked.
-
Make sure the Doctype in the webhook exactly matches (Job Applicant, not HR Applicant or a custom one).
7. Double Check: Docker Networking
If your webhook points to an external URL:
-
Ensure that container can resolve and reach it (especially if you’re using hostnames or internal networks).
-
Try:
docker exec -it erpnext-backend-1 curl -I https://your-webhook-url
If that fails, it won’t fire successfully (Frappe retries silently but logs an error).
TL;DR: Likely Cause and Fix
| Possible Cause |
Symptom |
Fix |
Workflow changes bypass on_update |
No webhook fired |
Use after_save instead |
| Condition syntax mismatch |
Preview works, but runtime fails |
Use proper quotes and test in console |
| Disabled webhook |
No trigger at all |
Enable it |
| Networking issue |
Webhook trigger error |
Test with curl inside backend |
| Misconfigured Doctype |
No trigger |
Verify exact Doctype name |
If you want, you can share:
-
The Doctype name (e.g., Job Applicant or Job Application),
-
The exact way you’re changing the status (“via Workflow” or “manual edit + Save”).
Then I can tell you exactly which event (on_update, after_save, or on_change) to use in that Doctype.