fix(mcp): keep store receiver bound in scene event operations#489
fix(mcp): keep store receiver bound in scene event operations#489konevenkatesh wants to merge 1 commit into
Conversation
appendSceneEvent and listSceneEvents detached the store methods before invoking them (const append = this.requireStore().appendSceneEvent; append(options)), so `this` was undefined inside store implementations that rely on it — SqliteSceneStore.withWriteTransaction in particular. Every save_scene, create_from_template, and live-sync mutation routed through the facade failed with "undefined is not an object (evaluating 'this.withWriteTransaction')" even though the SQLite write succeeded. Invoke the methods on the store instance instead, and add facade-level regression tests covering both the bound-receiver path and the stores-without-scene-events fallback. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want reviews to match your repository better? Bugbot Learning can learn team-specific rules from PR activity. A team admin can enable Learning in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit ef80fa3. Configure here.
|
|
||
| afterEach(async () => { | ||
| await fs.rm(rootDir, { recursive: true, force: true }) | ||
| }) |
There was a problem hiding this comment.
Test leaves SQLite handle open
Low Severity
The afterEach hook removes the temporary database directory without closing the SqliteSceneStore instance. This can leave SQLite database files locked, causing fs.rm to fail (e.g., EBUSY on Windows) and potentially leaking file handles. Other tests correctly close the store before cleanup.
Reviewed by Cursor Bugbot for commit ef80fa3. Configure here.


Summary
SceneOperationsFacade.appendSceneEventandlistSceneEventsdetached the store methods from the store instance before invoking them:For store implementations that rely on
this—SqliteSceneStorecallsthis.withWriteTransaction(...)insideappendSceneEvent— the detached call crashes with:Because the underlying SQLite write happens inside the transaction helper that never runs (append) or runs after the row insert (depending on path), every
save_scene,create_from_template, and live-sync mutation routed through the MCP facade reported this error to the client even when the scene row itself had been persisted, making the MCP server unusable for headless scene building.Reproduction
Run any scene save through the
pascal-mcpCLI under Bun (e.g. connect an MCP client and callsave_scene, or any template/live-sync tool that appends scene events). The tool call returnsundefined is not an object (evaluating 'this.withWriteTransaction').Fix
Invoke the optional methods on the store instance so the receiver stays bound:
Same change for
listSceneEvents.Tests
Added
packages/mcp/src/operations/scene-operations.test.ts:createSceneOperationsbacked by a realSqliteSceneStore— this fails with the exactTypeErrorabove before the fix and passes after;appendSceneEvent→null,listSceneEvents→scene_events_unavailable).bun testinpackages/mcp: 295 pass, 0 fail.bun checkreports no findings in the changed files.🤖 Generated with Claude Code
Note
Low Risk
Small, localized fix mirroring other facade store calls; tests cover the failure mode and optional-store fallbacks.
Overview
Fixes a
thisbinding bug inSceneOperationsFacadethat broke MCP scene event APIs when backed bySqliteSceneStore.appendSceneEventandlistSceneEventsno longer copy store methods into locals before calling them. They now invokestore.appendSceneEvent(...)andstore.listSceneEvents(...)on the store instance so methods that usethis(e.g.withWriteTransactionduring append) run correctly. That removes theundefined is not an object (evaluating 'this.withWriteTransaction')failures on headless saves and related tools.Adds
scene-operations.test.ts: a regression test throughcreateSceneOperations+SqliteSceneStore, plus coverage when the store omits scene events (null/scene_events_unavailable).Reviewed by Cursor Bugbot for commit ef80fa3. Bugbot is set up for automated code reviews on this repo. Configure here.