From 001d242af6f93276fb2ca28cfcc36c68258f0d65 Mon Sep 17 00:00:00 2001 From: Jaakko Husso Date: Wed, 3 Jun 2026 18:40:41 +0300 Subject: [PATCH] fix(core): Preserve filesystem binding when reading workspace files (no-changelog) (#31667) Co-authored-by: Riqwan Thamir --- .../__tests__/workspace-files.test.ts | 23 +++++++++++++++++++ .../src/workspace/workspace-files.ts | 6 ++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/packages/@n8n/instance-ai/src/workspace/__tests__/workspace-files.test.ts b/packages/@n8n/instance-ai/src/workspace/__tests__/workspace-files.test.ts index f4aa255d218..b8d49a42aa7 100644 --- a/packages/@n8n/instance-ai/src/workspace/__tests__/workspace-files.test.ts +++ b/packages/@n8n/instance-ai/src/workspace/__tests__/workspace-files.test.ts @@ -46,6 +46,29 @@ describe('workspace-files', () => { expect(target.sandbox?.executeCommand).not.toHaveBeenCalled(); }); + it('preserves the filesystem as `this` when reading', async () => { + // Mirrors LazyRuntimeFilesystem.readFile, whose body dereferences `this` + // (e.g. `this.getFilesystem()`). A detached call would lose the binding + // and throw "Cannot read properties of undefined". + class ThisDependentFilesystem { + private readonly files = new Map([['/tmp/manifest.json', '{"ok":true}']]); + + async readFile(path: string): Promise { + const content = this.files.get(path); + if (content === undefined) throw new Error('missing'); + return await Promise.resolve(content); + } + + async writeFile(): Promise { + await Promise.resolve(); + } + } + + const target: WorkspaceFileTarget = { filesystem: new ThisDependentFilesystem() }; + + await expect(readWorkspaceFile(target, '/tmp/manifest.json')).resolves.toBe('{"ok":true}'); + }); + it('reads via sandbox commands when no filesystem reader is available', async () => { const { target } = createWorkspaceTarget(new Map([['/tmp/manifest.json', '{"ok":true}']])); target.filesystem = { diff --git a/packages/@n8n/instance-ai/src/workspace/workspace-files.ts b/packages/@n8n/instance-ai/src/workspace/workspace-files.ts index e834c569ffb..b764b453216 100644 --- a/packages/@n8n/instance-ai/src/workspace/workspace-files.ts +++ b/packages/@n8n/instance-ai/src/workspace/workspace-files.ts @@ -37,10 +37,10 @@ export async function readWorkspaceFile( filePath: string, options?: WorkspaceFileOptions, ): Promise { - const readFile = workspace.filesystem?.readFile; - if (readFile) { + const filesystem = workspace.filesystem; + if (filesystem?.readFile) { try { - return decodeWorkspaceFileContent(await readFile(filePath, { encoding: 'utf-8' })); + return decodeWorkspaceFileContent(await filesystem.readFile(filePath, { encoding: 'utf-8' })); } catch (error) { options?.logger?.debug(`${resourceLabel(options)} filesystem read missed`, { path: filePath,