Profile field edits can be clobbered by a slow-loading initial fetch (pronouns, timezone, avatar decoration) #47

Closed
opened 2026-09-12 01:51:12 -04:00 by jared · 0 comments
Owner

Severity: medium · Type: bug · Confidence: high

Location: src/app/features/settings/account/Profile.tsx:755-770 (ProfilePronouns), src/app/features/settings/account/Profile.tsx:879-899 (ProfileTimezone), src/app/features/settings/account/ProfileDecoration.tsx:71-86 (ProfileDecoration)

Problem

All three components fetch the current server value in a mount-time useEffect and, on resolution, unconditionally call both the "live" setter and the "saved" setter — there is no cancellation flag and no check for whether the user has already changed the field. If the user edits pronouns/timezone or clicks a decoration before the initial GET resolves (plausible on a slow network, a cold cache, or a federated/rate-limited homeserver), the async .then() overwrites the user's fresh, untouched edit back to the stale server value with no warning and no way to tell it happened.

How to trigger

Open Settings → Account → Profile on a connection with noticeable latency (or throttle in devtools) and immediately change Pronouns/Timezone/Avatar Decoration before the page's initial profile fetch completes.

Suggested fix

Guard each fetch effect with a mounted/cancelled flag and skip applying the fetched value once the user has started editing — mirror the statusDirtyRef pattern already used by the adjacent ProfileStatus component in the same file, which exists specifically to avoid this class of bug.


Filed from the September 2026 client audit (branch lotus @ 4bea4895).

**Severity:** medium · **Type:** bug · **Confidence:** high **Location:** `src/app/features/settings/account/Profile.tsx:755-770` (ProfilePronouns), `src/app/features/settings/account/Profile.tsx:879-899` (ProfileTimezone), `src/app/features/settings/account/ProfileDecoration.tsx:71-86` (ProfileDecoration) ### Problem All three components fetch the current server value in a mount-time `useEffect` and, on resolution, unconditionally call both the "live" setter and the "saved" setter — there is no cancellation flag and no check for whether the user has already changed the field. If the user edits pronouns/timezone or clicks a decoration before the initial GET resolves (plausible on a slow network, a cold cache, or a federated/rate-limited homeserver), the async `.then()` overwrites the user's fresh, untouched edit back to the stale server value with no warning and no way to tell it happened. ### How to trigger Open Settings → Account → Profile on a connection with noticeable latency (or throttle in devtools) and immediately change Pronouns/Timezone/Avatar Decoration before the page's initial profile fetch completes. ### Suggested fix Guard each fetch effect with a mounted/cancelled flag and skip applying the fetched value once the user has started editing — mirror the `statusDirtyRef` pattern already used by the adjacent `ProfileStatus` component in the same file, which exists specifically to avoid this class of bug. --- _Filed from the September 2026 client audit (branch `lotus` @ 4bea4895)._
jared added this to the Audit 2026-09 · Medium & Low milestone 2026-09-12 01:51:12 -04:00
jared added the bugpriority: mediumarea: settings labels 2026-09-12 01:51:12 -04:00
jared self-assigned this 2026-09-12 01:51:12 -04:00
jared closed this issue 2026-09-12 19:46:17 -04:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
2026-11-14
Dependencies

No dependencies set.

Reference: LotusGuild/cinny#47