From dc77ae2aef7fa3308aa5c258af4296352eea020d Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 5 Jun 2026 11:09:48 +0200 Subject: [PATCH] fix(agents): guard extension load error formatting --- src/agents/sessions/extensions/loader.test.ts | 30 +++++++++++++++++++ src/agents/sessions/extensions/loader.ts | 13 +++++++- 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/agents/sessions/extensions/loader.test.ts b/src/agents/sessions/extensions/loader.test.ts index b5d96bbe6abc..866675242a21 100644 --- a/src/agents/sessions/extensions/loader.test.ts +++ b/src/agents/sessions/extensions/loader.test.ts @@ -86,4 +86,34 @@ export default async function(api) { expect(result.extensions).toHaveLength(1); expect(Array.from(result.extensions[0]?.tools.keys() ?? [])).toEqual(["healthy_lookup"]); }); + + it("reports hostile extension factory failures without crashing the loader", async () => { + const dir = await mkdtemp(join(tmpdir(), "openclaw-extension-load-error-")); + tempDirs.push(dir); + const extensionPath = join(dir, "extension.ts"); + await writeFile( + extensionPath, + ` +export default async function() { + const error = new Error("factory failed"); + Object.defineProperty(error, "message", { + get() { + throw new Error("message denied"); + }, + }); + throw error; +} +`, + ); + + const result = await loadExtensions([extensionPath], dir); + + expect(result.extensions).toEqual([]); + expect(result.errors).toEqual([ + { + path: extensionPath, + error: "Failed to load extension: Unknown extension load error", + }, + ]); + }); }); diff --git a/src/agents/sessions/extensions/loader.ts b/src/agents/sessions/extensions/loader.ts index 0eb57aee8de7..808a5a91b0a5 100644 --- a/src/agents/sessions/extensions/loader.ts +++ b/src/agents/sessions/extensions/loader.ts @@ -487,6 +487,17 @@ function createExtension(extensionPath: string, resolvedPath: string): Extension }; } +function describeExtensionLoadError(err: unknown): string { + try { + if (err instanceof Error) { + return err.message || err.name || "Unknown extension load error"; + } + return String(err); + } catch { + return "Unknown extension load error"; + } +} + async function loadExtension( extensionPath: string, cwd: string, @@ -510,7 +521,7 @@ async function loadExtension( return { extension, error: null }; } catch (err) { - const message = err instanceof Error ? err.message : String(err); + const message = describeExtensionLoadError(err); return { extension: null, error: `Failed to load extension: ${message}` }; } }