{"record":{"id":"9d2e64769ea941e4","repo":"vitejs/vite","slug":"package-subpath-relativeid-is-not-defined-by","errorCode":null,"errorMessage":"Package subpath '${relativeId}' is not defined by \"exports\" in ${path.join(dir, 'package.json')}.","messagePattern":"Package subpath '(.+?)' is not defined by \"exports\" in (.+?)\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/vite/src/node/plugins/resolve.ts","lineNumber":1081,"sourceCode":"      const { file, postfix } = splitFileAndPostfix(relativeId)\n      const exportsId = resolveExportsOrImports(\n        data,\n        file,\n        options,\n        'exports',\n        externalize,\n      )\n      if (exportsId !== undefined) {\n        relativeId = exportsId + postfix\n      } else {\n        relativeId = undefined\n      }\n    } else {\n      // not exposed\n      relativeId = undefined\n    }\n    if (!relativeId) {\n      throw new Error(\n        `Package subpath '${relativeId}' is not defined by \"exports\" in ` +\n          `${path.join(dir, 'package.json')}.`,\n      )\n    }\n  } else if (options.mainFields.includes('browser') && isObject(browserField)) {\n    // resolve without postfix (see #7098)\n    const { file, postfix } = splitFileAndPostfix(relativeId)\n    const mapped = mapWithBrowserField(file, browserField)\n    if (mapped) {\n      relativeId = mapped + postfix\n    } else if (mapped === false) {\n      setResolvedCache(id, browserExternalId, options)\n      return browserExternalId\n    }\n  }\n\n  if (relativeId) {\n    const resolved = tryFsResolve(","sourceCodeStart":1063,"sourceCodeEnd":1099,"githubUrl":"https://github.com/vitejs/vite/blob/b4d66fee14d970f45b8a6f3d7d6aee73ca9b88ab/packages/vite/src/node/plugins/resolve.ts#L1063-L1099","documentation":"During package resolution, Vite honors the 'exports' field of package.json. If the requested subpath does not match any exports entry (or exports is an array/non-object, treated as 'not exposed'), relativeId becomes undefined and Vite throws a Node-style ERR_PACKAGE_PATH_NOT_EXPORTED-style message naming the package.json path.","triggerScenarios":"Importing 'pkg/somesubpath' where pkg's package.json has an 'exports' map that does not list that subpath. The throw happens in resolvePackageImports when splitFileAndPostfix + resolveExportsOrImports returns undefined.","commonSituations":"Deep imports the package author did not export (e.g. 'lodash/fp/internal'), version upgrades that tightened the exports map, or a typo in the subpath. Also seen when a package switches from CommonJS (no exports) to ESM-with-exports and previously-working deep imports break.","solutions":["Import only the paths the package documents as exported (often just the package root).","If you control the package, add the subpath to its 'exports' map.","Check the package version against your assumption — a downgrade/upgrade may have changed exports.","If a transitive dep is doing the bad import, update that dependency or open an issue upstream."],"exampleFix":"// before\nimport _ from 'mylib/internal/util'\n// after — use an exported path\nimport _ from 'mylib'\n// or, if you own mylib, in package.json:\n{ \"exports\": { \".\": \"./dist/index.js\", \"./internal/util\": \"./dist/internal/util.js\" } }","handlingStrategy":"validation","validationCode":"// Verify a subpath is exported before importing\nimport { resolveExports } from 'resolve.exports'\nfunction assertExported(pkgJsonPath, subpath, conditions) {\n  const pkg = JSON.parse(readFileSync(pkgJsonPath, 'utf8'))\n  const resolved = resolveExports(pkg, subpath, { conditions })\n  if (!resolved) throw new Error(`${subpath} is not exported by ${pkgJsonPath}`)\n}","typeGuard":"function isExportedSubpath(pkg, subpath): boolean {\n  const exp = pkg.exports\n  if (!exp || typeof exp !== 'object' || Array.isArray(exp)) return false\n  return subpath in exp || '.' in exp // simplified\n}","tryCatchPattern":"try {\n  return await import('pkg/subpath')\n} catch (e) {\n  if (/not defined by \"exports\"/.test(e.message)) {\n    return await import('pkg') // fall back to root export\n  }\n  throw e\n}","preventionTips":["Prefer root imports over deep imports unless documented.","When upgrading a dependency, diff its exports map.","If you own the package, expose the subpaths your consumers need."],"tags":["resolve","exports","package-json","esm"],"backgroundTag":null,"analyzedSha":"b4d66fee14d970f45b8a6f3d7d6aee73ca9b88ab","analyzedAt":"2026-08-11T11:49:19.515Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}