Skip to content

v5.4.1 - afterSave Callbacks Ignore the Handler Return Value

Choose a tag to compare

@AdrianCurtin AdrianCurtin released this 07 Jun 15:30
· 29 commits to main since this release

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 afterSave webhook handler that returns a Parse::Object (instead of true or nil) no longer silently skips the model's after_create and after_save callbacks 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 recommended beforeSave pattern, easy to copy into an afterSave by mistake — previously cancelled dirty-gated side effects such as after_save :send_email. The response is also normalized to true, 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 afterSave response body and resolves success even if the handler raises, so an afterSave handler'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.
end

Commit: d1779f1
Author: Adrian Curtin
Date: June 7, 2026