vitejs/vite · error · Error
[vite] transform failed for module '${url}'${importer ? ` im
Error message
[vite] transform failed for module '${url}'${importer ? ` imported from '${importer}'` : ''}. What it means
Vite's fetchModule (used by the SSR/module-runner pipeline to load a module for evaluation) calls environment.transformRequest(url) and expects a non-null transform result. If the transform returns null/undefined — meaning every plugin's transform/load hook failed or returned nothing for that module — Vite cannot proceed and throws this generic transform-failure error. It is a catch-all when the pipeline produced no usable code.
Source
Thrown at packages/vite/src/node/ssr/fetchModule.ts:94
? 'module'
: 'commonjs'
return { externalize: file, type }
}
url = unwrapId(url)
const mod = await environment.moduleGraph.ensureEntryFromUrl(url)
const cached = !!mod.transformResult
// if url is already cached, we can just confirm it's also cached on the server
if (options.cached && cached) {
return { cache: true }
}
let result = await environment.transformRequest(url)
if (!result) {
throw new Error(
`[vite] transform failed for module '${url}'${
importer ? ` imported from '${importer}'` : ''
}.`,
)
}
if (options.inlineSourceMap !== false) {
result = inlineSourceMap(mod, result, options.startOffset)
}
// remove shebang
if (result.code[0] === '#')
result.code = result.code.replace(/^#!.*/, (s) => ' '.repeat(s.length))
return {
code: result.code,
file: mod.file,
id: mod.id!,View on GitHub (pinned to 89620f09af)
Solutions
- Check the Vite dev server console / error overlay for the underlying transform error from the plugin that failed — this error is a symptom, the real cause is logged above it.
- Verify the module at the URL in the message actually exists and is readable; fix any syntax/import errors in that file.
- Audit custom plugins: ensure their transform/load hooks either return a result or return null cleanly without throwing.
- Clear node_modules/.vite cache and restart the dev server to eliminate stale transform results.
Example fix
// before — a plugin that throws during transform breaks fetchModule
transform(code, id) {
return someTransformThatCanFail(code) // returns undefined on failure
}
// after — return null explicitly so Vite skips rather than produces no result
transform(code, id) {
try {
return { code: someTransformThatCanFail(code) }
} catch {
return null
}
} Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check the module resolves before relying on fetchModule
import { isExternalUrl, isBuiltin } from 'vite'
async function canFetch(environment, url) {
try {
await environment.moduleGraph.ensureEntryFromUrl(url)
return true
} catch {
return false
}
} Try / catch
try {
const result = await fetchModule(environment, url, importer)
} catch (e) {
if (e instanceof Error && e.message.startsWith('[vite] transform failed')) {
// inspect server logs for the underlying plugin transform error
logger.error('Module transform failed; check plugin errors for', url)
} else {
throw e
}
} Prevention
- Keep the dev-server console visible during SSR — the real transform error is logged above this one.
- Ensure custom plugins' transform hooks never throw uncaught; return null to skip cleanly.
- Invalidate/clear the module graph (.vite cache) after plugin upgrades.
When it happens
Trigger: A module that is neither transformed by any plugin nor resolvable as a file causes transformRequest to return null inside fetchModule. This happens when a plugin's transform hook throws silently, a plugin returns null unexpectedly, the file is empty or has an unsupported extension with no matching loader, or the module graph entry has a stale/corrupt transformResult that was cleared.
Common situations: SSR with ssrLoadModule or the module runner importing a file that a custom plugin fails to handle. A plugin error during development that leaves a module in a broken state. Conflicting plugin versions after an upgrade where a transform hook signature changed. Circular imports or files with syntax errors that cause transforms to short-circuit.
Related errors
- [module runner] "import.meta.glob" is statically replaced du
- [module runner] Dynamic access of "import.meta.env" is not s
- [module runner] "import.meta.resolve" is not supported.
- Vite module runner has been closed.
- Module "${url}" was mistakenly invalidated during fetch phas
AI-assisted analysis of vitejs/vite@89620f09af (2026-08-03).
Data as JSON: /data/errors/7f9d774cbff4f195.json.
Report an issue: GitHub.