Skip to content

user-settings: a fresh user can never write conditionally — If-Match "0" is rejected against the ETag the GET itself served #442

Description

@angela-helios

GET /_user/settings serves the empty document as a real representation: {} with ETag: "0". But check_if_match maps version 0 to "no current representation", so If-Match: "0" — the exact validator the GET handed out — always fails with 412. A client doing read-then-conditional-write (saved-queries.js does exactly this for the roaming recents/saved lists) deadlocks forever on a fresh user: every 412 retry re-reads "0" and fails again.

It went unnoticed because nav.js used to PATCH {nav: …} without If-Match on the first toggle, unconditionally creating the document — after which version ≥ 1 and conditional writes work. #438 removed nav.js, and the e2e suite now fails deterministically on a fresh database (queries.spec.ts › a run is recorded under the Recent disclosure, three PATCH → 412 in the trace of PR #440's CI run).

Fix: in crates/rest/src/handlers/user_settings.rs::check_if_match, evaluate concrete tag lists against version.to_string() including version 0, so the advertised validator round-trips. If-Match: * keeps requiring an actually-stored document. The storage layer is already coherent — all four backends treat Some(0) as "expect absent" and insert.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions