You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
studio: no draft save sends If-Match, so two editors (or two tabs) silently overwrite each other's metadata edits #11773
Filing gate ① — product defect with a named location and a reproduction. reach: two admin sessions editing the same object in Studio: the later autosave replaced the earlier one's saved field, verified on GET /api/v1/meta/object/<name>?state=draft.
Who acts on it: objectui triage → the Studio / app-shell owner. ⛔ Not a claim. Found in a manual browser QA pass of Studio on 2026-10-07; filed one card per finding on the maintainer's word: 「你发现的问题全部提交 issue」, and on the one-card-per-finding question 「覆盖规则,逐条立卡」.
What happens
Studio's draft saves are last-writer-wins on the whole document. Tab A saved Plural label = Repair Tickets (A2) (the server draft showed it). Tab B, opened before A's save, then changed Description; B's autosave sent its stale copy and the server draft afterwards had nopluralLabel. Neither tab saw a 409, banner or toast. Reproduced twice.
Reproduction
Open /studio/<writable pkg>/data?surface=object:<obj> in tab A and tab B; in both go Advanced → Settings.
Tab A: change Plural label, tab out, wait for "Saved". GET /api/v1/meta/object/<obj>?state=draft&package=<pkg> shows the new pluralLabel.
Tab B: change Description, tab out, wait for "Saved".
Same GET: description is B's value and pluralLabel is gone.
Expected
B's save is refused as a conflict (the draft changed since B read it) and B is offered reload / review / overwrite.
Where it comes from (read in source)
MetadataClient already supports optimistic concurrency — its save options carry ifMatch, sent as the If-Match header — and the framework honours If-Match. A search of packages/app-shell/src for ifMatch returns no hit: no Studio save path passes the version it read.
Suggested direction (triage to rule)
Thread the version from each read into every draft save (ifMatch), and on 409 show a conflict dialog. This is the multi-admin case Studio is built for, so it is worth doing before more autosave surfaces are added.
Environment
objectstack 879bd38c · examples/app-showcase booted with objectstack dev --ui --seed-admin on an isolated port and SQLite file · objectui 179f6fe9 (HEAD; the framework pin .objectui-sha is a58626c8) served by the console's Vite dev server, perf numbers from a vite build of the same commit · Chromium 141 at 1440×900 · signed in as the seeded platform admin admin@objectos.ai unless stated.
Duplicate check
Semantic issue search on objectstack-ai/objectui (open and closed), studio concurrent edit lost update If-Match optimistic concurrency autosave overwrite: 6 hits (0 open, 6 closed).
Semantic issue search on objectstack-ai/objectstack (open and closed), metadata draft save If-Match etag optimistic concurrency lost update two editors: 8 hits (0 open, 8 closed).
Semantic issue search on objectstack-ai/objectui (open and closed), MetadataClient save ifMatch never passed by studio designer two tabs overwrite: 8 hits (0 open, 8 closed).
Filing gate ① — product defect with a named location and a reproduction. reach: two admin sessions editing the same object in Studio: the later autosave replaced the earlier one's saved field, verified on
GET /api/v1/meta/object/<name>?state=draft.Who acts on it: objectui triage → the Studio / app-shell owner. ⛔ Not a claim. Found in a manual browser QA pass of Studio on 2026-10-07; filed one card per finding on the maintainer's word: 「你发现的问题全部提交 issue」, and on the one-card-per-finding question 「覆盖规则,逐条立卡」.
What happens
Studio's draft saves are last-writer-wins on the whole document. Tab A saved Plural label =
Repair Tickets (A2)(the server draft showed it). Tab B, opened before A's save, then changed Description; B's autosave sent its stale copy and the server draft afterwards had nopluralLabel. Neither tab saw a 409, banner or toast. Reproduced twice.Reproduction
/studio/<writable pkg>/data?surface=object:<obj>in tab A and tab B; in both go Advanced → Settings.GET /api/v1/meta/object/<obj>?state=draft&package=<pkg>shows the newpluralLabel.descriptionis B's value andpluralLabelis gone.Expected
B's save is refused as a conflict (the draft changed since B read it) and B is offered reload / review / overwrite.
Where it comes from (read in source)
MetadataClientalready supports optimistic concurrency — its save options carryifMatch, sent as theIf-Matchheader — and the framework honoursIf-Match. A search ofpackages/app-shell/srcforifMatchreturns no hit: no Studio save path passes the version it read.Suggested direction (triage to rule)
Thread the version from each read into every draft save (
ifMatch), and on 409 show a conflict dialog. This is the multi-admin case Studio is built for, so it is worth doing before more autosave surfaces are added.Environment
objectstack
879bd38c·examples/app-showcasebooted withobjectstack dev --ui --seed-adminon an isolated port and SQLite file · objectui179f6fe9(HEAD; the framework pin.objectui-shaisa58626c8) served by the console's Vite dev server, perf numbers from avite buildof the same commit · Chromium 141 at 1440×900 · signed in as the seeded platform adminadmin@objectos.aiunless stated.Duplicate check
Dedupe words: concurrent edit lost update · If-Match not sent · autosave overwrite · optimistic concurrency studio
Filed by Claude Code (session
session_01D76mrPJrSSdaKRxR2rvrMG) from that QA pass.Blocked-by: objectstack-ai/objectstack#22114
Generated by Claude Code