Repository navigation
fix(editor): never write back a recipe renamed or deleted in another tab - #809
Merged
Merged
Conversation
An editor tab still open on a recipe that was renamed or deleted elsewhere (another tab, another device) autosaved to its old path, and `PUT /api/recipes` creates a missing file: the old name came back beside the new one, or the deleted recipe reappeared. The editor's own rename was already guarded; other tabs were not. The editor now saves with `If-Match: *`, and the save endpoint refuses it with `412` when the file is missing, checked under the lock rename and delete take. The editor then stops saving, says the file was renamed or deleted elsewhere, and keeps the text as unsaved, so leaving asks first. `PUT` without the header still creates a file. Since in-editor rename came in with 2c6e839 (cooklang#623). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MmrM91dHzvQoaerCcR9wra
LeMyst
marked this pull request as ready for review
October 28, 2026 21:01
This was referenced Oct 28, 2026
dubadub
pushed a commit
that referenced
this pull request
Nov 3, 2026
The editor's save status (Modified, Saving..., Saved, Save failed, and since #809 "Not saved: renamed or deleted elsewhere") and its save notices were written in English in the template, whatever the page's language. Three of them already had messages in every locale, unused. The status and the notices now come from the locales: the existing `editor-unsaved-changes`, `editor-saving`, `editor-saved` and `editor-save-failed`, and new `editor-not-saved-gone`, `editor-save-failed-detail` and `editor-file-gone` in all nine. The refusal of a file renamed or deleted elsewhere is explained in the page's words instead of the server's English message. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MmrM91dHzvQoaerCcR9wra
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #808
An editor tab open on a recipe that is then renamed or deleted elsewhere no longer writes the old file back.
PUT /api/recipes/{path}honoursIf-Match: *(RFC 9110). When the file is missing it answers412instead of creating it. The check runs underRECIPE_FILES, the lock rename and delete already take, so they can't slip in between the check and the write. No entity tags are issued, so any otherIf-Matchvalue gets412too. Without the header,PUTstill creates a file, as documented, so other API clients are unaffected.If-Match: *, so the editor never creates a recipe file (/newdoes that). On a412it stops autosaving, shows "Not saved: renamed or deleted elsewhere" in the save status (sticky while typing), and shows the server's message once. The text stays unsaved, so leaving the page asks first and the changes can be copied out.docs/api.mdis regenerated with the header's description.Tests
recipe_file_api_test::save_with_if_match_never_creates_a_file:If-Match: *saves over an existing file, and refuses a missing.cookor.menuwith412without creating it;If-Matchvalue is refused;PUTwithout the header still creates the file.editor-rename.spec.ts, two new cases, each with two tabs on one recipe: tab A renames it (or it's deleted), then tab B types. B shows the status, the old name is not created again, B sends no further saves, and its text is still unsaved. Without the editor's header both fail (B shows "Saved" and the old file is back).cargo clippy --all-targetsclean,cargo test --workspace1873 passed. Full chromium Playwright run green, apart from the specs that spawntarget/debug/cook, which doesn't exist in my local setup. The shopping-list specs were rerun with--workers=1, as on CI.The status text is English, like the rest of the editor's save statuses (the editor isn't translated yet).
🤖 Generated with Claude Code
https://claude.ai/code/session_01MmrM91dHzvQoaerCcR9wra