diff --git a/openclaw.mjs b/openclaw.mjs index 248db52ea44..099c7f6a406 100755 --- a/openclaw.mjs +++ b/openclaw.mjs @@ -1,6 +1,7 @@ #!/usr/bin/env node import module from "node:module"; +import { fileURLToPath } from "node:url"; const MIN_NODE_MAJOR = 22; const MIN_NODE_MINOR = 12; @@ -47,6 +48,20 @@ if (module.enableCompileCache && !process.env.NODE_DISABLE_COMPILE_CACHE) { const isModuleNotFoundError = (err) => err && typeof err === "object" && "code" in err && err.code === "ERR_MODULE_NOT_FOUND"; +const isDirectModuleNotFoundError = (err, specifier) => { + if (!isModuleNotFoundError(err)) { + return false; + } + + const expectedUrl = new URL(specifier, import.meta.url); + if ("url" in err && err.url === expectedUrl.href) { + return true; + } + + const message = "message" in err && typeof err.message === "string" ? err.message : ""; + return message.includes(fileURLToPath(expectedUrl)); +}; + const installProcessWarningFilter = async () => { // Keep bootstrap warnings consistent with the TypeScript runtime. for (const specifier of ["./dist/warning-filter.js", "./dist/warning-filter.mjs"]) { @@ -57,7 +72,7 @@ const installProcessWarningFilter = async () => { return; } } catch (err) { - if (isModuleNotFoundError(err)) { + if (isDirectModuleNotFoundError(err, specifier)) { continue; } throw err; @@ -72,8 +87,8 @@ const tryImport = async (specifier) => { await import(specifier); return true; } catch (err) { - // Only swallow missing-module errors; rethrow real runtime errors. - if (isModuleNotFoundError(err)) { + // Only swallow direct entry misses; rethrow transitive resolution failures. + if (isDirectModuleNotFoundError(err, specifier)) { return false; } throw err;