Admin general settings form never saves: dotted react-hook-form names nest on input #322
Labels
No Label
area:auth
area:docs
area:export
area:ops
area:storage
area:supply-chain
auth
backend
blocked
collab
deployment
docs
effort:L
effort:M
effort:S
frontend
plugins
qa
vs-nfd
vs-nfd:blocker
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: stwaidele/dorfteich#322
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Found by Stefan while walking through the self-hosting guide (#320) on a fresh install, confirmed on dorfteich.online: changing the instance name under Admin -> Settings, saving, leaving and re-entering the page shows "Dorfteich" again.
Root cause (reproduced in a jsdom test): the general card and the quota card in AdminSettingsPage.tsx share one useForm whose fields are registered with DOTTED names (register('instance.name') etc.). react-hook-form treats dots as path separators: display works (its get() falls back to the literal flat key from the server data), but typing writes the new value into a NESTED object. handleSubmit therefore produces a body like
PATCH /admin/settings validates with a .strict() schema, so the unknown nested key rejects the request (and even without strict, the stale flat keys would write the old values back). The new value never reaches the database.
Affected fields (everything submitted via this form's onSubmit): instance.name, instance.defaultLocale, auth.registrationMode, classification.newPageDefault, classification.uploadPolicy, and the quota.* number fields. Every other card on the page builds its PATCH body by hand with flat keys and is fine.
Why no test caught it: every e2e spec that changes admin settings PATCHes the API directly (collab.spec.ts:139, legal.spec.ts:17, members.spec.ts:25); none drives the general form through the UI.
Fix outline: