vitejs/vite · error · Error

[vite]: Rolldown failed to resolve import

Error message

[vite]: Rolldown failed to resolve import "${exporter}" from "${id}".
This is most likely unintended because it can break your application at runtime.
If you do want to externalize this module explicitly add it to
`build.rolldownOptions.external`

What it means

Rolldown emits an UNRESOLVED_IMPORT log for any specifier it cannot resolve. Vite's onRollupLog handler re-throws that log as an error unless the importer is a CommonJS external shim (?commonjs-external). The message tells you which exporter could not be resolved from which file and points at build.rolldownOptions.external as the explicit-externalize escape hatch.

Solutions

  1. Install the missing package: npm install <exporter>.
  2. If it is a peer/runtime dep, add it to build.rollupOptions.external (or ssr.external for SSR).
  3. Fix typos in the import specifier; check it matches the package name exactly.
  4. For Node built-ins in SSR code, ensure the environment is configured as node, not browser.

Example fix

// before
// app imports 'lodash.debounce' but it is not installed
// after (option A)
//   npm install lodash.debounce
// after (option B - externalize)
build: { rollupOptions: { external: ['lodash.debounce'] } }
Defensive patterns

Strategy: try-catch

Validate before calling

const fs = require('fs');
function canResolve(specifier, importer) {
  try { require.resolve(specifier, { paths: [require('path').dirname(importer)] }); return true; } catch { return false; }
}

Try / catch

try {
  await vite.build();
} catch (e) {
  if (e && /Rolldown failed to resolve import/.test(String(e.message))) {
    const m = e.message.match(/import "([^"]+)"/);
    const missing = m?.[1];
    external.push(missing);
    await vite.build();
  } else throw e;
}

Prevention

When it happens

Trigger: Source code imports a bare specifier that is not installed, not a Node builtin, and not listed in external. Typical with peer deps, optional deps, or typos. Also when an SSR build references a package that lives only in dependenciesUsed but is not externalized.

Common situations: Forgetting to install a package; importing a peer dependency without declaring it external; importing Node built-ins (fs, path) in client code; referencing a workspace package whose name does not match.

Related errors


AI-assisted analysis of vitejs/vite@b4d66fee14 (2026-08-11). Data as JSON: /api/errors/5218bf9614cec969. Report an issue: GitHub.

Appendix: source

Thrown at packages/vite/src/node/build.ts:1133

  }
}

export function onRollupLog(
  level: LogLevel,
  log: RollupLog,
  environment: Environment,
): void {
  const debugLogger = createDebugger('vite:build')
  const viteLog: LogOrStringHandler = (logLeveling, rawLogging) => {
    const logging =
      typeof rawLogging === 'object' ? rawLogging : { message: rawLogging }

    if (logging.code === 'UNRESOLVED_IMPORT') {
      const id = logging.id
      const exporter = logging.exporter
      // throw unless it's commonjs external...
      if (!id || !id.endsWith('?commonjs-external')) {
        throw new Error(
          `[vite]: Rolldown failed to resolve import "${exporter}" from "${id}".\n` +
            `This is most likely unintended because it can break your application at runtime.\n` +
            `If you do want to externalize this module explicitly add it to\n` +
            `\`build.rolldownOptions.external\``,
        )
      }
    }

    if (logLeveling === 'warn') {
      if (
        logging.plugin === 'rollup-plugin-dynamic-import-variables' &&
        dynamicImportWarningIgnoreList.some((msg) =>
          logging.message.includes(msg),
        )
      ) {
        return
      }

View on GitHub (pinned to b4d66fee14)