vitejs/vite · error · Error
[module runner] "import.meta.resolve" is not supported.
Error message
[module runner] "import.meta.resolve" is not supported.
What it means
The default module-runner import.meta object implements `resolve()` as a function that always throws. Resolution of arbitrary specifiers at runtime requires filesystem/resolve machinery that the default runner does not provide. The Node-specific variant (`createNodeImportMeta`) does implement `resolve`, so the throw only occurs under the default meta.
Solutions
- Pass a custom `createImportMeta` to the ModuleRunner that supplies a working `resolve` (the runner's `createImportMetaResolver` helper can back it).
- Use the Node module-runner evaluator path (`createNodeImportMeta`) which implements `resolve`.
- Avoid `import.meta.resolve` in runner-executed code; resolve specifiers at build time or via the runner transport instead.
Example fix
// before
new ModuleRunner({ transport, /* default createImportMeta - resolve throws */ })
// module calls: import.meta.resolve('./foo')
// after
import { createNodeImportMeta } from 'vite/module-runner'
new ModuleRunner({ transport, createImportMeta: createNodeImportMeta }) Defensive patterns
Strategy: validation
Validate before calling
import { createNodeImportMeta } from 'vite/module-runner'
function runnerOptionsNeedsNodeResolve(opts: { createImportMeta?: unknown }) {
// if no custom createImportMeta provided AND code uses import.meta.resolve, swap in the Node variant
return opts.createImportMeta == null
}
// usage: if (runnerOptionsNeedsNodeResolve(opts)) opts.createImportMeta = createNodeImportMeta Type guard
function importMetaResolveAvailable(meta: any): boolean {
try { return typeof meta.resolve === 'function' && meta.resolve !== createDefaultImportMetaResolveStub() } catch { return false }
} Try / catch
try {
return import.meta.resolve(id)
} catch (e) {
if (e instanceof Error && /import.meta.resolve.*not supported/.test(e.message)) {
// resolve via an alternative (e.g. node:module createRequire)
} else throw e
} Prevention
- If runner code needs resolve(), pass createNodeImportMeta (or a custom createImportMeta) to ModuleRunner.
- Avoid import.meta.resolve in code shared between bundler and default runner.
When it happens
Trigger: Calling `import.meta.resolve(id)` in code executed by a module runner that was constructed with the default `createImportMeta` (no custom `createImportMeta` option and not the Node evaluator path).
Common situations: Sharing a module between a bundler build and the runner where the bundler supports `import.meta.resolve` but the runner default does not. Library code that probes `import.meta.resolve` for feature detection.
Related errors
- Cannot send non-custom events from the client to the server.
- Cannot send non-custom events from the server to the client.
- [module runner] Dynamic access of "import.meta.env" is not…
- [module runner] Failed to load
- [module runner] "import.meta.glob" is statically replaced…
AI-assisted analysis of vitejs/vite@b4d66fee14 (2026-08-11).
Data as JSON: /api/errors/d777f9b4c2f3d5ce.
Report an issue: GitHub.
Appendix: source
Thrown at packages/vite/src/module-runner/createImportMeta.ts:26
throw new Error(
`[module runner] Dynamic access of "import.meta.env" is not supported. Please, use "import.meta.env.${String(p)}" instead.`,
)
},
})
export function createDefaultImportMeta(
modulePath: string,
): ModuleRunnerImportMeta {
const href = posixPathToFileHref(modulePath)
const filename = modulePath
const dirname = posixDirname(modulePath)
return {
filename: isWindows ? toWindowsPath(filename) : filename,
dirname: isWindows ? toWindowsPath(dirname) : dirname,
url: href,
env: envProxy,
resolve(_id: string, _parent?: string) {
throw new Error('[module runner] "import.meta.resolve" is not supported.')
},
// should be replaced during transformation
glob() {
throw new Error(
`[module runner] "import.meta.glob" is statically replaced during ` +
`file transformation. Make sure to reference it by the full name.`,
)
},
}
}
/**
* Create import.meta object for Node.js.
*/
export function createNodeImportMeta(
modulePath: string,
): ModuleRunnerImportMeta {
const defaultMeta = createDefaultImportMeta(modulePath)View on GitHub (pinned to b4d66fee14)