diff --git a/src/browser/modules/NativeModuleResolver.test.ts b/src/browser/modules/NativeModuleResolver.test.ts index 044576ac13..1619e8fc44 100644 --- a/src/browser/modules/NativeModuleResolver.test.ts +++ b/src/browser/modules/NativeModuleResolver.test.ts @@ -167,6 +167,26 @@ describe("optional native resolution acquisition", () => { message: expect.stringContaining("REA_BROWSER_EXECUTABLE"), }); }); + it.each(["relative/chromium", ""])( + "retains an invalid selected browser path %j without launching", + async (executable) => { + const provider = new NativeModuleResolver( + { REA_BROWSER_EXECUTABLE: executable }, + () => { + throw new Error("must not launch"); + }, + ); + const result = await provider.resolve(input); + if (result.ok) throw new Error("expected configuration refusal"); + expect(projectAnalysisError(result.error)).toMatchObject({ + code: "capability_unavailable", + details: { + reason: "invalid_browser_executable", + diagnostics: { executable }, + }, + }); + }, + ); it("does not acquire a browser after caller cancellation", async () => { const controller = new AbortController(); const reason = { request: "opaque admission cancellation" }; diff --git a/src/browser/modules/NativeModuleResolver.ts b/src/browser/modules/NativeModuleResolver.ts index 9bf0ba59dc..4383a27e0c 100644 --- a/src/browser/modules/NativeModuleResolver.ts +++ b/src/browser/modules/NativeModuleResolver.ts @@ -119,10 +119,15 @@ export class NativeModuleResolver implements WebModuleResolutionPort { new AnalysisCapabilityUnavailableError( "native-module-resolver", OPERATION, - "missing_browser_executable", + executable === undefined + ? "missing_browser_executable" + : "invalid_browser_executable", { userMessage: "Provide an absolute REA_BROWSER_EXECUTABLE for a caller-supplied Chromium browser supporting import.meta.resolve. REA installs no browser.", + ...(executable === undefined + ? {} + : { diagnostics: { executable } }), }, ), ); diff --git a/tests/acceptance/webModuleCli.test.ts b/tests/acceptance/webModuleCli.test.ts index 57509e6770..468d1551b9 100644 --- a/tests/acceptance/webModuleCli.test.ts +++ b/tests/acceptance/webModuleCli.test.ts @@ -136,3 +136,35 @@ cliTest( } }, ); + +cliTest( + "retains an invalid caller-selected browser path in trace errors", + async ({ cli }) => { + const root = await createTestTempDirectory("rea-module-browser-config-"); + const artifacts = webModuleArtifactsFixture('import "./dep.js"'); + const files = join(root, "files"); + await mkdir(join(files, "modules"), { recursive: true }); + await writeFile(join(files, "modules", "main.js"), artifacts.source); + const manifest = join(root, "manifest.json"); + await writeFile( + manifest, + JSON.stringify({ + ...artifacts.manifest, + output_directory: root, + analysis_input: { input_path: files, format: "directory" }, + }), + ); + const result = await cli.run({ + arguments: ["trace-web-module-imports", manifest, "0", "--json"], + environment: { REA_BROWSER_EXECUTABLE: "relative/chromium" }, + }); + expect(result.exitCode).toBe(1); + expect(result.json).toMatchObject({ + code: "capability_unavailable", + details: { + reason: "invalid_browser_executable", + diagnostics: { executable: "relative/chromium" }, + }, + }); + }, +);