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
Bug: Taxonomy breaks on first open after SPA navigation (no page reload)
What was broken
When a user creates a new project with a Taxonomy label config and opens Quick View (or the labeling interface) without a full page reload, the editor fails with:
Error: [mobx-state-tree] Cannot add an object to a state tree if it is already
part of the same or another state tree. Tried to assign an object to
'/annotationStore/sharedStores/taxonomy', but it lives already at
'/annotationStore/sharedStores/taxonomy'
The UI renders broken. A full page refresh fixes it — until the next new project.
Root cause
SharedChoiceStore (used by Taxonomy and Choices) maintains two module-level singletons that live for the lifetime of the browser tab:
exportconstStores=newMap();// SharedStoreModel instancesconstStoreIds=newSet();// IDs of already-created stores
These caches are intentional — they let multiple annotations on the same task share one store instance. But they are never cleared on SPA navigation.
When the user navigates to a new project without a reload:
The old LSF instance is torn down, but Stores still holds the old SharedStoreModel instance for "taxonomy" — an instance that was previously attached to (and detached from) the old MST tree
The new LSF initializes, calls initializeStore → afterReset() → tries to attach the same stale instance to the new tree
MST sees the node as still "belonging" to another tree and throws
This was further aggravated by a performance optimization (PR #9495 / BROS-827) that wrapped resetState() and initializeStore() in the same runInAction() block. Within a single MobX transaction, detach() (called by beforeReset) doesn't commit before afterReset tries to re-attach the same stores — causing the same error even during normal task switching.
Fix (two changes)
1. lsf-sdk.js — split the runInAction batch
initializeStore is moved outside the runInAction block so detach() commits before afterReset() re-attaches shared stores:
// resetState + toggleInterface + assignTask batched together (safe)runInAction(()=>{this.lsf.resetState();this.lsf.toggleInterface(...);this.lsf.assignTask(task);});// initializeStore runs AFTER the transaction commitsthis.lsf.initializeStore(lsfTask);
2. extender.js — defensive afterReset()
afterReset() now catches the MST error when a cached store instance is stale (still attached to a dead tree from a previous LSF lifecycle). On failure, it recreates the store from its snapshot and updates the global cache:
afterReset(){Stores.forEach((store,key)=>{try{self.addSharedStore(store);}catch{// Stale instance from previous LSF lifecycle — recreate from snapshotconstsnapshot=safeGetSnapshot(store)??{id: key,children: []};constfreshStore=SharedStoreModel.create(snapshot);Stores.set(key,freshStore);self.addSharedStore(freshStore);}});},
Fix 1 addresses task-switching. Fix 2 addresses first-open after SPA navigation. Together they cover all known paths to this error.
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
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.
Bug: Taxonomy breaks on first open after SPA navigation (no page reload)
What was broken
When a user creates a new project with a Taxonomy label config and opens Quick View (or the labeling interface) without a full page reload, the editor fails with:
The UI renders broken. A full page refresh fixes it — until the next new project.
Root cause
SharedChoiceStore(used by Taxonomy and Choices) maintains two module-level singletons that live for the lifetime of the browser tab:These caches are intentional — they let multiple annotations on the same task share one store instance. But they are never cleared on SPA navigation.
When the user navigates to a new project without a reload:
Storesstill holds the oldSharedStoreModelinstance for"taxonomy"— an instance that was previously attached to (and detached from) the old MST treeinitializeStore→afterReset()→ tries to attach the same stale instance to the new treeThis was further aggravated by a performance optimization (PR #9495 / BROS-827) that wrapped
resetState()andinitializeStore()in the samerunInAction()block. Within a single MobX transaction,detach()(called bybeforeReset) doesn't commit beforeafterResettries to re-attach the same stores — causing the same error even during normal task switching.Fix (two changes)
1.
lsf-sdk.js— split therunInActionbatchinitializeStoreis moved outside therunInActionblock sodetach()commits beforeafterReset()re-attaches shared stores:2.
extender.js— defensiveafterReset()afterReset()now catches the MST error when a cached store instance is stale (still attached to a dead tree from a previous LSF lifecycle). On failure, it recreates the store from its snapshot and updates the global cache:Fix 1 addresses task-switching. Fix 2 addresses first-open after SPA navigation. Together they cover all known paths to this error.