Skip to content

[6.x] Fix save button hanging forever when a save hook fails - #15194

Merged
jasonvarga merged 2 commits into
6.xfrom
fix/save-pipeline-hook-rejection
Aug 13, 2026
Merged

[6.x] Fix save button hanging forever when a save hook fails#15194
jasonvarga merged 2 commits into
6.xfrom
fix/save-pipeline-hook-rejection

Conversation

@jasonvarga

Copy link
Copy Markdown
Member

Fixes a bug where the Save button could spin forever, locking the form until a page reload — losing unsaved work.

BeforeSaveHooks and AfterSaveHooks wrapped the hook run in a promise but only wired up the fulfilment path. If a saving or saved hook rejected — or threw, which becomes a rejection — nothing ever called resolve or reject, so the promise never settled. The pipeline stalled mid-flight, Finish never ran, and the saving state stayed true. The only sign anything went wrong was an unhandled rejection in the console.

Since saving and saved are public extension points, a single throwing hook in an addon or in a site's own CP JS takes out saving entirely for that form.

The rejection is now propagated. Pipeline.through() also resets the saving state for any error, not just PipelineStopped — otherwise propagating the rejection would only have converted the hang into a different one.

Also added the missing .catch to the user publish form, the one publish form with no rejection handler at all.

To reproduce on 6.x: register Statamic.$hooks.on('entry.saving', (resolve, reject) => reject(new Error('boom'))) in your CP JS, then save an entry.

jasonvarga and others added 2 commits August 13, 2026 17:00
BeforeSaveHooks and AfterSaveHooks only wired up the fulfilment path, so a
rejecting or throwing saving/saved hook left the promise unsettled. The
pipeline stalled, saving state stayed true, and the form locked up with no
diagnostic beyond a console message.

Propagate the rejection, and reset the saving state for any error rather than
only PipelineStopped, so a rejection doesn't just become a different hang.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@jasonvarga
jasonvarga merged commit 816c5a8 into 6.x Aug 13, 2026
65 checks passed
@jasonvarga
jasonvarga deleted the fix/save-pipeline-hook-rejection branch August 13, 2026 21:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant