What happened?
Calling create_from_template with save: true throws:
save_failed: undefined is not an object (evaluating 'this.withWriteTransaction')
Root cause: In SceneOperationsFacade.appendSceneEvent() (dist/operations/scene-operations.js), the store method is destructured from its object and then called as a plain function — losing the this binding:
// BUGGY (before fix)
async appendSceneEvent(options) {
const append = this.requireStore().appendSceneEvent; // method extracted
if (!append) return null;
return append(options); // called without this → this.withWriteTransaction is undefined
}
When append(options) is called without a receiver, this inside SqliteSceneStore.appendSceneEvent is undefined (strict mode), and the first line return this.withWriteTransaction(...) throws.
The same pattern in listSceneEvents has the identical bug (store method destructured and called without binding).
Call chain:
create-from-template.js:126 → appendLiveSceneEvent(bridge, ...)
→ live-sync.js:61 operations.appendSceneEvent({...})
→ scene-operations.js:169 const append = this.requireStore().appendSceneEvent ← loses this
→ scene-operations.js:172 append(options)
→ sqlite-scene-store.js:385 this.withWriteTransaction(...) ← this is undefined → crash
Steps to reproduce
- Install
@pascal-app/mcp v0.3.2 globally: bun install -g @pascal-app/mcp
- Set
PASCAL_DATA_DIR to a writable directory
- Call the
create_from_template MCP tool with { "id": "two-bedroom", "save": true }
- Observe
save_failed: undefined is not an object (evaluating 'this.withWriteTransaction')
Minimal reproduction (Node/Bun script):
import { SqliteSceneStore } from '@pascal-app/mcp/dist/storage/sqlite-scene-store.js';
import { SceneBridge } from '@pascal-app/mcp/dist/bridge/scene-bridge.js';
import { createSceneOperations } from '@pascal-app/mcp/dist/operations/scene-operations.js';
const store = new SqliteSceneStore({ dbPath: ':memory:' });
const bridge = new SceneBridge();
const operations = createSceneOperations({ bridge, store });
const meta = await operations.saveScene({ name: 'test', graph: { nodes: {}, rootNodeIds: [] }, saveMode: 'draft', publish: false, operation: 'test' });
// This line throws:
await operations.appendSceneEvent({ sceneId: meta.id, version: meta.version, kind: 'test', graph: { nodes: {}, rootNodeIds: [] } });
// Error: undefined is not an object (evaluating 'this.withWriteTransaction')
Expected behavior
create_from_template with save: true should save the scene and return SceneMeta without error. The appendSceneEvent call that follows the save should succeed, appending a live event to the SQLite store.
Browser & OS
N/A — MCP stdio server, Bun 1.3.13 / macOS 25.5.0 (Darwin). Not a browser issue.
Screenshots or screen recordings
No response
Additional context
Package version: @pascal-app/mcp 0.3.2
Runtime: Bun 1.3.13
Affected methods: SceneOperationsFacade.appendSceneEvent and SceneOperationsFacade.listSceneEvents in dist/operations/scene-operations.js
One-line fix (two places in scene-operations.js):
// appendSceneEvent
- async appendSceneEvent(options) {
- const append = this.requireStore().appendSceneEvent;
- if (!append)
- return null;
- return append(options);
- }
+ async appendSceneEvent(options) {
+ const store = this.requireStore();
+ if (!store.appendSceneEvent)
+ return null;
+ return store.appendSceneEvent(options);
+ }
// listSceneEvents
- async listSceneEvents(id, options) {
- const list = this.requireStore().listSceneEvents;
- if (!list) {
- throw new Error('scene_events_unavailable');
- }
- return list(id, options);
- }
+ async listSceneEvents(id, options) {
+ const store = this.requireStore();
+ if (!store.listSceneEvents) {
+ throw new Error('scene_events_unavailable');
+ }
+ return store.listSceneEvents(id, options);
+ }
Verified locally: after applying the patch, saveScene + appendSceneEvent + listSceneEvents all succeed against an in-memory SQLite store. Related to #696 (same package, different method).
What happened?
Calling
create_from_templatewithsave: truethrows:Root cause: In
SceneOperationsFacade.appendSceneEvent()(dist/operations/scene-operations.js), the store method is destructured from its object and then called as a plain function — losing thethisbinding:When
append(options)is called without a receiver,thisinsideSqliteSceneStore.appendSceneEventisundefined(strict mode), and the first linereturn this.withWriteTransaction(...)throws.The same pattern in
listSceneEventshas the identical bug (store method destructured and called without binding).Call chain:
create-from-template.js:126→appendLiveSceneEvent(bridge, ...)→
live-sync.js:61operations.appendSceneEvent({...})→
scene-operations.js:169const append = this.requireStore().appendSceneEvent← losesthis→
scene-operations.js:172append(options)→
sqlite-scene-store.js:385this.withWriteTransaction(...)←thisisundefined→ crashSteps to reproduce
@pascal-app/mcpv0.3.2 globally:bun install -g @pascal-app/mcpPASCAL_DATA_DIRto a writable directorycreate_from_templateMCP tool with{ "id": "two-bedroom", "save": true }save_failed: undefined is not an object (evaluating 'this.withWriteTransaction')Minimal reproduction (Node/Bun script):
Expected behavior
create_from_templatewithsave: trueshould save the scene and returnSceneMetawithout error. TheappendSceneEventcall that follows the save should succeed, appending a live event to the SQLite store.Browser & OS
N/A — MCP stdio server, Bun 1.3.13 / macOS 25.5.0 (Darwin). Not a browser issue.
Screenshots or screen recordings
No response
Additional context
Package version:
@pascal-app/mcp0.3.2Runtime: Bun 1.3.13
Affected methods:
SceneOperationsFacade.appendSceneEventandSceneOperationsFacade.listSceneEventsindist/operations/scene-operations.jsOne-line fix (two places in scene-operations.js):
Verified locally: after applying the patch,
saveScene+appendSceneEvent+listSceneEventsall succeed against an in-memory SQLite store. Related to #696 (same package, different method).