{"id":"577c1b6686ebb7c3","repo":"vitejs/vite","slug":"failed-to-resolve-json-stringify-id-this-pack","errorCode":null,"errorMessage":"Failed to resolve ${JSON.stringify(id)}. This package is ESM only but it was tried to load by `require`. See https://vite.dev/guide/troubleshooting.html#this-package-is-esm-only for more details.","messagePattern":"Failed to resolve (.+?)\\. This package is ESM only but it was tried to load by `require`\\. See https://vite\\.dev/guide/troubleshooting\\.html#this-package-is-esm-only for more details\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/vite/src/node/config.ts","lineNumber":2585,"sourceCode":"            }\n\n            const isImport = isESM || kind === 'dynamic-import'\n            let idFsPath: string | undefined\n            try {\n              idFsPath = nodeResolveWithVite(id, importer, {\n                root,\n                isRequire: !isImport,\n              })\n            } catch (e) {\n              if (!isImport) {\n                let canResolveWithImport = false\n                try {\n                  canResolveWithImport = !!nodeResolveWithVite(id, importer, {\n                    root,\n                  })\n                } catch {}\n                if (canResolveWithImport) {\n                  throw new Error(\n                    `Failed to resolve ${JSON.stringify(\n                      id,\n                    )}. This package is ESM only but it was tried to load by \\`require\\`. See https://vite.dev/guide/troubleshooting.html#this-package-is-esm-only for more details.`,\n                  )\n                }\n              }\n              throw e\n            }\n            if (!idFsPath) return\n            // always no-externalize json files as rolldown does not support import attributes\n            if (idFsPath.endsWith('.json')) {\n              return idFsPath\n            }\n\n            if (idFsPath && isImport) {\n              idFsPath = pathToFileURL(idFsPath).href\n            }\n            return { id: idFsPath, external: true }","sourceCodeStart":2567,"sourceCodeEnd":2603,"githubUrl":"https://github.com/vitejs/vite/blob/89620f09afcfef6b35e7bb8660132ab5b4d0cd3b/packages/vite/src/node/config.ts#L2567-L2603","documentation":"Thrown during Vite's config-file bundling when a dependency is resolved as a CommonJS `require` but the package only ships ESM. The resolver first attempts `nodeResolveWithVite` with `isRequire: true`; on failure it retries without that flag, and if the import-style resolve succeeds it concludes the package is ESM-only and rejects the require. It points to the official troubleshooting guide because mixing CJS config files with ESM-only deps is a well-known interop failure.","triggerScenarios":"A `vite.config.cjs` (or a project without `\"type\": \"module\"`) that `require()`s an ESM-only package, or any config whose bundled graph contains a `require(...)` of an ESM-only dep. The resolveId hook in config.ts:2577 runs with `isImport=false`, fails, then the retry at config.ts:2580 succeeds, triggering the throw at config.ts:2585.","commonSituations":"Using a newer ESM-only release of a library (e.g. `execa`, `got`, `node-fetch` v3+, `chalk` v5+) inside a legacy `.cjs` config; monorepo root lacking `\"type\": \"module\"`; scaffolding tools that emit CJS configs by default; upgrading a dependency whose major version moved to ESM-only.","solutions":["Rename the config to `vite.config.mjs` (or add `\"type\": \"module\"` to package.json) so it is treated as ESM and uses `import` instead of `require`.","Replace any `require('pkg')` calls in the config with dynamic `import()` or static `import`.","Downgrade the offending dependency to a version that still ships a CJS build, or find a CJS-compatible alternative.","If you must keep CJS, pre-bundle the dep yourself or import it via a wrapper that re-exports from an ESM entry."],"exampleFix":"// before (vite.config.cjs)\nconst { defineConfig } = require('vite')\nconst execa = require('execa') // execa v6+ is ESM-only\n\n// after (rename to vite.config.mjs)\nimport { defineConfig } from 'vite'\nimport { execa } from 'execa'","handlingStrategy":"validation","validationCode":"// Before writing a CJS config that requires a dep, verify it ships CJS:\nconst pkg = require.resolve('<dep>/package.json')\nconst meta = require(pkg)\nconst hasCjs = meta.main || (meta.exports && JSON.stringify(meta.exports).includes('require'))\nif (!hasCjs && (meta.type === 'module' || meta.exports?.import)) {\n  throw new Error('<dep> is ESM-only; convert this config to ESM (.mjs)')\n}","typeGuard":"// Narrow a config format to whether require() is safe\nfunction isCjsSafeConfig(configPath: string): boolean {\n  return /\\.c?js$/.test(configPath) && !fs.existsSync(path.join(process.cwd(), 'package.json'))\n    ? false\n    : require('./package.json').type !== 'module'\n}","tryCatchPattern":null,"preventionTips":["Default new projects to ESM: set \"type\": \"module\" and use vite.config.mjs.","Never require() in a Vite config — use static/dynamic import.","When upgrading a dep, check its changelog for an ESM-only major bump."],"tags":["esm","cjs","config","interop","resolution"],"analyzedSha":"89620f09afcfef6b35e7bb8660132ab5b4d0cd3b","analyzedAt":"2026-08-03T19:28:02.920Z","schemaVersion":2}