v5.4.1 - afterSave Callbacks Ignore the Handler Return Value
afterSave callbacks no longer depend on the handler return value
An afterSave webhook handler that returns a Parse::Object instead of true/nil no longer suppresses the model's after_create / after_save ActiveModel callbacks on client-initiated saves. Parse Server discards the afterSave response body entirely — it resolves the request as a success even when the handler throws — so the handler's return value carries no signal back to the server and must not gate callback dispatch.
Changes
- FIXED: An
afterSavewebhook handler that returns aParse::Object(instead oftrueornil) no longer silently skips the model'safter_createandafter_savecallbacks on client/REST/JS-initiated saves. The dispatch decision now depends only on the request origin, never on what the handler returned. A trusted Ruby-initiated save still skips the webhook-side callbacks (the local save chain already fired them, avoiding a double-run), while a client-initiated save always fires them. Returning the object — the recommendedbeforeSavepattern, easy to copy into anafterSaveby mistake — previously cancelled dirty-gated side effects such asafter_save :send_email. The response is also normalized totrue, so a returned object can no longer leak into the response body or the debug log.
Behavior Notes
- This affects only client/REST/JS-initiated saves, where the SDK never ran the model callbacks locally. Trusted Ruby-model saves are unchanged — their callbacks still run exactly once, through the local save chain.
- Parse Server ignores the
afterSaveresponse body and resolves success even if the handler raises, so anafterSavehandler's return value is not a control signal. Where a handler must signal failure, raise — do not rely on the return value.
Code Example
class Post < Parse::Object
property :title
after_save :reindex # now fires for client/REST/JS saves regardless
# of the afterSave webhook block's return value
end
Parse::Webhooks.route :after_save, "Post" do
parse_object # returning the object no longer suppresses :reindex
# Prefer returning `true` — Parse Server discards the afterSave response anyway.
endCommit: d1779f1
Author: Adrian Curtin
Date: June 7, 2026