{"record":{"id":"b079207d28ff8f6a","repo":"vitejs/vite","slug":"runtime-result-runtime-is-not-supported","errorCode":null,"errorMessage":"{ runtime: \"${result.runtime}\" } is not supported for assets in ${hostType} files: ${filename}","messagePattern":"(.+?) is not supported for assets in (.+?) files: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/plugin-legacy/src/index.ts","lineNumber":81,"sourceCode":"  filename: string,\n  type: 'asset' | 'public',\n  hostId: string,\n  hostType: 'js' | 'css' | 'html',\n  config: ResolvedConfig,\n  toRelative: (filename: string, importer: string) => string,\n): string {\n  const { renderBuiltUrl } = config.experimental\n  let relative = config.base === '' || config.base === './'\n  if (renderBuiltUrl) {\n    const result = renderBuiltUrl(filename, {\n      hostId,\n      hostType,\n      type,\n      ssr: !!config.build.ssr,\n    })\n    if (typeof result === 'object') {\n      if (result.runtime) {\n        throw new Error(\n          `{ runtime: \"${result.runtime}\" } is not supported for assets in ${hostType} files: ${filename}`,\n        )\n      }\n      if (typeof result.relative === 'boolean') {\n        relative = result.relative\n      }\n    } else if (result) {\n      return result\n    }\n  }\n  if (relative && !config.build.ssr) {\n    return toRelative(filename, hostId)\n  } else {\n    // @ts-expect-error `decodedBase` is internal\n    return joinUrlSegments(config.decodedBase, filename)\n  }\n}\nfunction getBaseInHTML(urlRelativePath: string, config: ResolvedConfig) {","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/vitejs/vite/blob/b4d66fee14d970f45b8a6f3d7d6aee73ca9b88ab/packages/plugin-legacy/src/index.ts#L63-L99","documentation":"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.","triggerScenarios":"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`.","commonSituations":"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.","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."],"exampleFix":"// before\nexperimental: {\n  renderBuiltUrl(filename, { hostType }) {\n    return { runtime: `window.__assets[${JSON.stringify(filename)}]` }\n  },\n},\n// after\nexperimental: {\n  renderBuiltUrl(filename, { hostType, type }) {\n    if (hostType === 'html') return `/static/${filename}` // static for HTML hosts\n    return { runtime: `window.__assets[${JSON.stringify(filename)}]` }\n  },\n},","handlingStrategy":"validation","validationCode":"// Validate renderBuiltUrl return shape before enabling plugin-legacy\nimport type { ResolvedConfig } from 'vite'\nfunction assertLegacySafeRenderBuiltUrl(cfg: ResolvedConfig) {\n  const fn = cfg.experimental?.renderBuiltUrl\n  if (!fn) return\n  // simulate with an html-host asset to detect a runtime return\n  const probe = fn('assets/x.js', { hostId: 'index.html', hostType: 'html', type: 'asset', ssr: false })\n  if (probe && typeof probe === 'object' && 'runtime' in probe && probe.runtime) {\n    throw new Error('renderBuiltUrl returns { runtime } for HTML assets - incompatible with plugin-legacy')\n  }\n}","typeGuard":"function isStaticBuiltUrlResult(r: unknown): r is string | { relative?: boolean } {\n  if (r == null) return true\n  if (typeof r === 'string') return true\n  if (typeof r === 'object' && r !== null && !('runtime' in r && (r as any).runtime)) return true\n  return false\n}","tryCatchPattern":"try {\n  await vite.build(config)\n} catch (e) {\n  if (e instanceof Error && /is not supported for assets in .* files/.test(e.message)) {\n    // fix renderBuiltUrl to return a static path for HTML hostType, then rebuild\n  } else throw e\n}","preventionTips":["Branch renderBuiltUrl on hostType and never return { runtime } when hostType === 'html'.","When adding plugin-legacy to a project, audit experimental.renderBuiltUrl for runtime returns."],"tags":["plugin-legacy","render-built-url","asset-path","html","build"],"backgroundTag":null,"analyzedSha":"b4d66fee14d970f45b8a6f3d7d6aee73ca9b88ab","analyzedAt":"2026-08-11T11:49:19.515Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}