vitejs/vite · error · Error
" } is not supported for assets in files
Error message
{ runtime: "${result.runtime}" } is not supported for assets in ${hostType} files: ${filename} What it means
Thrown by plugin-legacy's internal toOutputFilePathInHtml helper when Vite's experimental.renderBuiltUrl hook returns an object containing a non-empty `runtime` string. Runtime-resolved URLs are deferred to the browser, but plugin-legacy generates static HTML/CSS/JS host tags whose asset URLs must be baked in at build time, so a runtime value is impossible to honor here. The message echoes the offending runtime value, the host file type, and the asset filename so you can locate the mismatch.
Solutions
- In your `renderBuiltUrl` callback, return a plain string (or `{ relative: boolean }`) instead of `{ runtime: ... }` for assets referenced from HTML hosts.
- Branch the `renderBuiltUrl` logic on `hostType`/`type` so HTML-served assets get a static path while module assets can still use runtime resolution.
- Remove the `experimental.renderBuiltUrl` option if you do not need runtime asset URLs.
- If you must keep runtime URLs, disable plugin-legacy for the affected build (set `renderLegacyChunks: false` / drop the plugin) so the legacy HTML path is not exercised.
Example fix
// before
experimental: {
renderBuiltUrl(filename, { hostType }) {
return { runtime: `window.__assets[${JSON.stringify(filename)}]` }
},
},
// after
experimental: {
renderBuiltUrl(filename, { hostType, type }) {
if (hostType === 'html') return `/static/${filename}` // static for HTML hosts
return { runtime: `window.__assets[${JSON.stringify(filename)}]` }
},
}, Defensive patterns
Strategy: validation
Validate before calling
// Validate renderBuiltUrl return shape before enabling plugin-legacy
import type { ResolvedConfig } from 'vite'
function assertLegacySafeRenderBuiltUrl(cfg: ResolvedConfig) {
const fn = cfg.experimental?.renderBuiltUrl
if (!fn) return
// simulate with an html-host asset to detect a runtime return
const probe = fn('assets/x.js', { hostId: 'index.html', hostType: 'html', type: 'asset', ssr: false })
if (probe && typeof probe === 'object' && 'runtime' in probe && probe.runtime) {
throw new Error('renderBuiltUrl returns { runtime } for HTML assets - incompatible with plugin-legacy')
}
} Type guard
function isStaticBuiltUrlResult(r: unknown): r is string | { relative?: boolean } {
if (r == null) return true
if (typeof r === 'string') return true
if (typeof r === 'object' && r !== null && !('runtime' in r && (r as any).runtime)) return true
return false
} Try / catch
try {
await vite.build(config)
} catch (e) {
if (e instanceof Error && /is not supported for assets in .* files/.test(e.message)) {
// fix renderBuiltUrl to return a static path for HTML hostType, then rebuild
} else throw e
} Prevention
- Branch renderBuiltUrl on hostType and never return { runtime } when hostType === 'html'.
- When adding plugin-legacy to a project, audit experimental.renderBuiltUrl for runtime returns.
When it happens
Trigger: Configuring `experimental.renderBuiltUrl` in vite.config to return `{ runtime: '...' }` (or `{ runtime: someVar }`) for an asset that ends up referenced from an HTML entry processed by @vitejs/plugin-legacy, then running a production build (`vite build`). The throw fires inside the legacy plugin's `transformIndexHtml`/asset path resolution because it calls the duplicated `toOutputFilePathInHtml`.
Common situations: Copying a `renderBuiltUrl` snippet from Vite docs (designed for CDN/runtime base URLs) into a project that also uses @vitejs/plugin-legacy. Migrating an app to a runtime-determined asset base (e.g. loading assets from a dynamic CDN) without realizing legacy HTML injection needs a static URL.
Related errors
- No corresponding legacy entry chunk found for
- No corresponding legacy polyfill chunk found for
- No corresponding modern polyfill chunk found for
- No matching HTML proxy module found from
- `renderLegacyChunks` and `renderModernChunks` cannot be…
AI-assisted analysis of vitejs/vite@b4d66fee14 (2026-08-11).
Data as JSON: /api/errors/b079207d28ff8f6a.
Report an issue: GitHub.
Appendix: source
Thrown at packages/plugin-legacy/src/index.ts:81
filename: string,
type: 'asset' | 'public',
hostId: string,
hostType: 'js' | 'css' | 'html',
config: ResolvedConfig,
toRelative: (filename: string, importer: string) => string,
): string {
const { renderBuiltUrl } = config.experimental
let relative = config.base === '' || config.base === './'
if (renderBuiltUrl) {
const result = renderBuiltUrl(filename, {
hostId,
hostType,
type,
ssr: !!config.build.ssr,
})
if (typeof result === 'object') {
if (result.runtime) {
throw new Error(
`{ runtime: "${result.runtime}" } is not supported for assets in ${hostType} files: ${filename}`,
)
}
if (typeof result.relative === 'boolean') {
relative = result.relative
}
} else if (result) {
return result
}
}
if (relative && !config.build.ssr) {
return toRelative(filename, hostId)
} else {
// @ts-expect-error `decodedBase` is internal
return joinUrlSegments(config.decodedBase, filename)
}
}
function getBaseInHTML(urlRelativePath: string, config: ResolvedConfig) {View on GitHub (pinned to b4d66fee14)