Skip to content

fix: Stop button now sends correct CSRF token, fixing silent cancel failures#157

Merged
manuelkiessling merged 2 commits intomainfrom
fix/stop-not-stopping
Feb 26, 2026
Merged

fix: Stop button now sends correct CSRF token, fixing silent cancel failures#157
manuelkiessling merged 2 commits intomainfrom
fix/stop-not-stopping

Conversation

@manuelkiessling
Copy link
Member

@manuelkiessling manuelkiessling commented Feb 25, 2026

Fixes #94.

When a user clicks Stop in the AI editor, handleCancel() was using a global document.querySelector for the CSRF token instead of scoping it to the form. The Twig template renders multiple CSRF tokens (one per form), and the global query returned the first match (Finish Session form's token with action conversation_finish) instead of the correct one (AI form's token with action chat_based_content_editor_run).

The backend validates against the expected action, so a wrong token triggered a 403 response. Since fetch() only throws on network errors—not HTTP errors— the error was silently swallowed and the cancel button remained stuck in "Stopping…" state forever, while the generation continued uninterrupted.

Changes:

  • Changed CSRF lookup in handleCancel() to use form-scoped query, matching the correct pattern already used in handleSubmit()
  • Added response.ok check after fetch to throw an error on non-2xx responses, allowing the catch block to re-enable the button for retry
  • Added integration tests verifying the CSRF token is sourced from the correct form and that button state recovers on cancel failure

This ensures cancel requests use the correct CSRF token and any future failures (network or server) re-enable the button so users can retry.


Note

Medium Risk
Touches cancel-request CSRF handling and client-side error flow; while localized and covered by new integration tests, mistakes could prevent users from stopping an in-flight generation.

Overview
Fixes the AI editor Stop flow by scoping CSRF lookup in handleCancel() to the cancel button’s containing form (instead of a global document.querySelector), preventing mismatched-token 403s when multiple forms exist.

Adds explicit response.ok handling for the cancel POST so HTTP failures trigger the existing retry UI (re-enabling the button and restoring its label), and extends the frontend integration test fixture/tests to validate correct CSRF sourcing and button recovery on cancel failure.

Written by Cursor Bugbot for commit d6864bc. This will update automatically on new commits. Configure here.

…ailures

When a user clicks Stop in the AI editor, handleCancel() was using a global
document.querySelector for the CSRF token instead of scoping it to the form.
The Twig template renders multiple CSRF tokens (one per form), and the global
query returned the first match (Finish Session form's token with action
conversation_finish) instead of the correct one (AI form's token with action
chat_based_content_editor_run).

The backend validates against the expected action, so a wrong token triggered
a 403 response. Since fetch() only throws on network errors—not HTTP errors—
the error was silently swallowed and the cancel button remained stuck in
"Stopping…" state forever, while the generation continued uninterrupted.

Changes:
- Changed CSRF lookup in handleCancel() to use form-scoped query, matching
  the correct pattern already used in handleSubmit()
- Added response.ok check after fetch to throw an error on non-2xx responses,
  allowing the catch block to re-enable the button for retry
- Added integration tests verifying the CSRF token is sourced from the
  correct form and that button state recovers on cancel failure

This ensures cancel requests use the correct CSRF token and any future
failures (network or server) re-enable the button so users can retry.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
@manuelkiessling manuelkiessling marked this pull request as ready for review February 26, 2026 15:49
@manuelkiessling manuelkiessling merged commit 09cf9b6 into main Feb 26, 2026
12 of 13 checks passed
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.

Stop action does not work properly

1 participant