Node.js Error

Error [ERR_INVALID_PACKAGE_CONFIG]: Invalid package config

error code: ERR_INVALID_PACKAGE_CONFIG

Error [ERR_INVALID_PACKAGE_CONFIG]: Invalid package config /path/to/package.json — complete causes and fixes for malformed JSON, invalid exports maps, and corrupted node_modules.

Quick Answer: Node.js throws Error [ERR_INVALID_PACKAGE_CONFIG]: Invalid package config /path/to/package.json when a package.json is either malformed JSON (trailing commas, comments, single quotes) or contains an invalid "exports", "imports", or "type" field. The fastest fixes are: (1) run node -e "require('./package.json')" to surface JSON syntax errors, (2) restructure a mixed-key "exports" object so all conditions are nested under ".", (3) do a clean npm install if the error is inside node_modules.

Exact Error Messages You Will See

Malformed JSON in your own package.json:
Error [ERR_INVALID_PACKAGE_CONFIG]: Invalid package config /project/package.json while importing /project/index.js. "name" is not valid JSON.
Mixed subpath and condition keys in exports:
Error [ERR_INVALID_PACKAGE_CONFIG]: Invalid package config /project/node_modules/some-package/package.json while importing /project/index.js. "exports" cannot contain some keys starting with '.' and some not. The exports object must either be an object of package subpath keys or an object of main entry condition name keys only.
Invalid exports target (does not start with ./):
Error [ERR_INVALID_PACKAGE_CONFIG]: Invalid package config /project/package.json. "exports" must start with "."
Corrupted / empty package.json in node_modules:
Error [ERR_INVALID_PACKAGE_CONFIG]: Invalid package config /project/node_modules/semver/package.json. "name" is not valid JSON.
Real-world: emotion / stylis (Next.js with-emotion example, Node.js 14+):
Error [ERR_INVALID_PACKAGE_CONFIG]: Invalid package config /project/node_modules/@emotion/babel-plugin/node_modules/stylis/package.json while importing /project/index.js. "exports" cannot contain some keys starting with '.' and some not. The exports object must either be an object of package subpath keys or an object of main entry condition name keys only.
Node.js 12+ internal module binding variant:
Error [ERR_INVALID_PACKAGE_CONFIG]: Invalid package config /project/node_modules/some-package/package.json while importing file:///project/index.js. "name" is not valid JSON.
node:internal/modules/package_json_reader:83
const parsed = modulesBinding.readPackageJSON(...)

Full Error Stack Trace

node:internal/modules/esm/resolve:855
  throw new ERR_INVALID_PACKAGE_CONFIG(fileURL, base, message);
        ^

Error [ERR_INVALID_PACKAGE_CONFIG]: Invalid package config
/project/node_modules/some-package/package.json while importing
file:///project/index.js. "exports" cannot contain some keys starting
with '.' and some not. The exports object must either be an object of
package subpath keys or an object of main entry condition name keys only.
    at packageExportsResolve (node:internal/modules/esm/resolve:855:13)
    at resolveExports (node:internal/modules/cjs/loader:573:36)
    at Module._findPath (node:internal/modules/cjs/loader:652:31)
    at Module._resolveFilename (node:internal/modules/cjs/loader:1091:27)
    at Module._load (node:internal/modules/cjs/loader:942:27)
    at Object.<anonymous> (/project/index.js:1:21) {
  code: 'ERR_INVALID_PACKAGE_CONFIG'
}

What is ERR_INVALID_PACKAGE_CONFIG?

ERR_INVALID_PACKAGE_CONFIG is thrown by Node.js when it reads a package.json file and finds either:

The error can originate from your project's own package.json, or from a package.json file deep inside node_modules. Node.js reads every package.json it encounters on the path from the importer to the target module, so a corrupted dependency can block your entire application from starting.

See the official Node.js error docs and the Packages documentation for the full specification.

Error Object Properties

PropertyValueNotes
err.code'ERR_INVALID_PACKAGE_CONFIG'Always this string; use for programmatic detection
err.messageIncludes the full path to the offending package.jsonParse it to find which file to fix
Exit code1Node.js terminates the process immediately
Catchable?No (startup) / Sometimes (dynamic import)Thrown during module resolution, often before user code runs

All Causes at a Glance

CauseSymptom in error messageFix
Trailing comma or comment in JSON "name" is not valid JSON or SyntaxError in message Remove trailing commas and comments; use node -e "require('./package.json')"
Mixing subpath and condition keys in "exports" "exports" cannot contain some keys starting with '.' and some not Nest condition keys under "." subpath
Exports target does not start with ./ "exports" must start with "." Change target values to relative paths starting with ./
Path traversal (..) in exports target Invalid package config ... Invalid "exports" target Use ./dist/file.js not ../other/file.js
Invalid "type" value Invalid package config ... "type" is not valid Set "type" to "module" or "commonjs" only
Empty or corrupted package.json in node_modules expected value at line 1 column 1 Delete node_modules and reinstall
CI-generated package.json with extra syntax SyntaxError or is not valid JSON Validate generated JSON with npx jsonlint before use
Dependency upgraded with broken exports map (e.g. elasticsearch-js, stylis) Mixed key error in node_modules/<pkg>/package.json Update or pin the dependency; use patch-package as stopgap
Node.js version stricter than when package was published Error appears after node upgrade only Update the dependency; or pin the old Node.js version temporarily

Cause 1 – Malformed JSON (trailing commas, comments, single quotes)

JSON does not allow trailing commas, JavaScript-style comments (// or /* */), or single-quoted strings. These are valid in JavaScript but illegal in JSON. Build scripts and code generators occasionally produce invalid JSON — CI pipelines are a common source.

// INVALID package.json — three JSON violations
{
  "name": "my-app",
  "version": "1.0.0",  // trailing comma after last key is illegal
  "type": "module",    /* comments are not valid JSON */
  'scripts': {         // single-quoted key is illegal
    "start": "node index.js",
  }                    // trailing comma inside object is illegal
}
// VALID package.json
{
  "name": "my-app",
  "version": "1.0.0",
  "type": "module",
  "scripts": {
    "start": "node index.js"
  }
}

Diagnosing the JSON syntax error

# Option 1: Node.js built-in — prints the offending line and column
node -e "require('./package.json')"

# Option 2: JSON.parse with readable output
node -e "JSON.parse(require('fs').readFileSync('./package.json','utf8'))"

# Option 3: dedicated JSON linter with line numbers and suggestions
npx jsonlint package.json
Pro tip: If your package.json is generated by a script (e.g. a CI pipeline that writes environment-specific fields), add a validation step immediately after generation: node -e "require('./package.json') && console.log('OK')". A non-zero exit code will fail the pipeline before Node.js ever tries to use the file.

Cause 2 – Mixed subpath and condition keys in "exports"

The "exports" field supports two distinct forms. At any given nesting level, all keys must be either subpath keys (start with .) or condition keys (do not start with .) — never a mix of both.

// INVALID — mixing '.' subpath keys with bare condition keys
{
  "exports": {
    "import": "./dist/esm/index.js",   // condition key (no dot prefix)
    "require": "./dist/cjs/index.js",  // condition key (no dot prefix)
    "./utils": "./dist/utils.js"       // subpath key (dot prefix)
  }
}
// → Error: "exports" cannot contain some keys starting with '.' and some not
// VALID — all conditions nested under the "." subpath key
{
  "exports": {
    ".": {
      "import": "./dist/esm/index.js",
      "require": "./dist/cjs/index.js",
      "default": "./dist/cjs/index.js"
    },
    "./utils": "./dist/utils.js"
  }
}
// ALSO VALID — top-level conditions only (no subpath keys at all)
{
  "exports": {
    "import": "./dist/esm/index.js",
    "require": "./dist/cjs/index.js",
    "default": "./dist/cjs/index.js"
  }
}

This was the cause behind the stylis package (used by Emotion and Next.js with-emotion examples) and the USWDS v2.11 issue. The fix in both cases was to nest the condition keys under a "." subpath key.

Cause 3 – Exports target that does not start with ./

Every value (the target path) in the "exports" and "imports" maps must be a relative path beginning with ./. Absolute file paths, bare package specifiers, and file:// URLs are rejected.

// INVALID export targets
{
  "exports": {
    ".": "/absolute/path/index.js",         // absolute path — invalid
    "./helper": "dist/helper.js",           // missing leading ./ — invalid
    "./other": "file:///app/dist/other.js", // file:// URL — invalid
    "./internal": "../sibling/index.js"     // path traversal (..) — invalid
  }
}
// VALID export targets
{
  "exports": {
    ".": "./dist/index.js",
    "./helper": "./dist/helper.js",
    "./package.json": "./package.json"
  }
}

Cause 4 – Invalid "type" field value

The "type" field controls whether .js files in the package are treated as CommonJS or ES modules. Node.js only accepts "module" or "commonjs" (case-sensitive). Any other string — including common typos — triggers ERR_INVALID_PACKAGE_CONFIG.

// INVALID "type" values
{ "type": "esm" }        // invalid
{ "type": "cjs" }        // invalid
{ "type": "es6" }        // invalid
{ "type": "modules" }    // invalid — extra 's'
{ "type": "Module" }     // invalid — case sensitive
// VALID "type" values
{ "type": "module" }     // treat .js files as ESM
{ "type": "commonjs" }   // treat .js files as CJS (also the default if omitted)

Cause 5 – Empty or corrupted package.json in node_modules

A failed or interrupted npm install can leave a package.json file empty or partially written. Node.js reads these files at module resolution time; an empty file causes a JSON parse error at line 1, column 1.

Real-world example: The zigbee2mqtt project reported this exact error (Invalid package config /app/node_modules/semver/package.json) after an upgrade that interrupted the npm install mid-write. The supabase auth-js package triggered the same issue in Deno's node_modules cache. The fix in all cases was a clean reinstall.
# Clean reinstall — macOS / Linux
rm -rf node_modules
rm -f package-lock.json
npm cache clean --force
npm install
# Clean reinstall — Windows (Command Prompt)
rd /s /q node_modules
del package-lock.json
npm cache clean --force
npm install
# Clean reinstall — Windows (PowerShell)
Remove-Item -Recurse -Force node_modules
Remove-Item package-lock.json
npm cache clean --force
npm install

Cause 6 – Malformed conditional exports (typos in condition names)

Node.js recognizes specific built-in condition names: "import", "require", "default", "node", "node-addons", "browser", "development", "production". Typos in these names do not throw ERR_INVALID_PACKAGE_CONFIG directly but cause no conditions to match, which can cascade into other errors. However, structurally invalid condition objects — such as a condition whose value is not a string, object, or array — do trigger it.

// INVALID — condition value is a number, not a path or nested object
{
  "exports": {
    ".": {
      "import": 1,         // must be a string path or nested object
      "require": null      // null is only valid to block a subpath, not a condition
    }
  }
}
// VALID — standard dual CJS/ESM exports with default fallback
{
  "exports": {
    ".": {
      "import": "./dist/index.mjs",
      "require": "./dist/index.cjs",
      "default": "./dist/index.cjs"
    }
  }
}
// VALID — nested conditions (Node.js + browser splits)
{
  "exports": {
    ".": {
      "node": {
        "import": "./dist/node.mjs",
        "require": "./dist/node.cjs"
      },
      "browser": "./dist/browser.js",
      "default": "./dist/index.js"
    }
  }
}

Fix for Dependency-Owned package.json (patch-package)

When the invalid package.json is inside a third-party dependency and no fixed release is available, use patch-package to apply a local fix that survives npm install.

# 1. Manually edit the offending file in node_modules
#    e.g. node_modules/some-package/package.json

# 2. Generate the patch file
npx patch-package some-package

# 3. Commit the patches/ directory to source control

# 4. Auto-apply after every install — add to package.json scripts:
#    "postinstall": "patch-package"

Fix for Node.js Version Mismatch in CI / Docker

If the error only appears on CI or in a Docker container but not locally, the Node.js version probably differs. Newer versions apply stricter validation.

# Check versions in both environments
node --version
npm --version

# Pin Node.js in a Dockerfile
FROM node:20-alpine

# Pin Node.js in .nvmrc (for nvm / fnm)
echo "20" > .nvmrc

# Pin in GitHub Actions
- uses: actions/setup-node@v4
  with:
    node-version: '20'
# Diagnose which package triggers the error in Node.js 22+
# The error message contains the full path — grep for it:
node index.js 2>&1 | grep "ERR_INVALID_PACKAGE_CONFIG"

Validating Your Own exports Map

Use this checklist before publishing a package with a non-trivial "exports" field.

// package.json validation checklist

// 1. Every target path starts with ./
//    INVALID: "dist/index.js"   VALID: "./dist/index.js"

// 2. No path traversal in targets
//    INVALID: "../lib/index.js"  VALID: "./lib/index.js"

// 3. No mixing subpath and condition keys at the same level
//    INVALID:
{
  "exports": {
    "import": "./esm.js",   // condition key
    "./helper": "./helper.js" // subpath key — MIXED!
  }
}
//    VALID:
{
  "exports": {
    ".": { "import": "./esm.js" },
    "./helper": "./helper.js"
  }
}

// 4. "default" is the last condition key in every conditions object
{
  "exports": {
    ".": {
      "import": "./dist/esm.js",
      "require": "./dist/cjs.js",
      "default": "./dist/cjs.js"   // always last
    }
  }
}

// 5. "type" is exactly "module" or "commonjs" — no other value

Debugging Checklist

  1. Read the full error message — it includes the absolute path to the offending package.json. Note whether it is your file or a dependency.
  2. If it is your file: run node -e "require('./package.json')" to surface the JSON syntax error with line and column.
  3. If the JSON is syntactically valid: inspect the "exports" field for mixed subpath and condition keys at the same level.
  4. Check the "type" field — it must be exactly "module" or "commonjs"; remove it entirely to default to CommonJS.
  5. If it is inside node_modules: delete node_modules and package-lock.json, run npm cache clean --force, then npm install.
  6. Compare node --version between the working environment (local) and the failing one (CI/Docker) — newer Node.js may reject previously tolerated configs.
  7. Check the dependency's GitHub issues and CHANGELOG for the error code — many popular packages (elasticsearch-js, stylis/emotion, USWDS) have had this exact bug.
  8. If no fixed version of the dependency exists, apply a patch with patch-package.
  9. For CI-generated package.json files: add node -e "require('./package.json') && console.log('valid')" as a validation step in your pipeline.

Frequently Asked Questions

What is ERR_INVALID_PACKAGE_CONFIG?

ERR_INVALID_PACKAGE_CONFIG is thrown by Node.js when it reads a package.json file and finds it either contains invalid JSON syntax or has a semantically invalid "exports", "imports", or "type" field. The error can come from your own package.json or from one inside node_modules.

How do I find which package.json is invalid?

The error message always includes the full file path. For example: Invalid package config /project/node_modules/some-package/package.json. Open that file to diagnose the problem. If it is your own package.json, run node -e "require('./package.json')" to get Node.js to point at the exact line and character.

How do I fix "exports cannot contain some keys starting with '.' and some not"?

This error means your exports object mixes subpath keys (starting with .) and bare condition keys (like import, require, default) at the same level. Nest all conditions under a "." key:

{
  "exports": {
    ".": {
      "import": "./dist/esm/index.js",
      "require": "./dist/cjs/index.js",
      "default": "./dist/cjs/index.js"
    },
    "./utils": "./dist/utils.js"
  }
}
Why does ERR_INVALID_PACKAGE_CONFIG appear after upgrading Node.js?

Newer Node.js versions apply stricter validation to package.json fields. A package.json that was silently tolerated on Node.js 16 may throw on Node.js 20 or 22. The elasticsearch-js package triggered this for Node.js 23 users in 2024. Fix by updating the problematic dependency to a version with a corrected package.json, or use patch-package while waiting for the upstream fix.

Why does ERR_INVALID_PACKAGE_CONFIG appear in production but not locally?

The most common reason is a different Node.js version in production or CI. Run node --version in both environments. A secondary cause is that npm ci in CI installs an exact transitive dependency version from the lockfile that differs from what npm install resolved locally — one of those versions has an invalid package.json. Fix by ensuring your lockfile is committed and both environments use the same Node.js version.

How do I validate a package.json from the command line?

Three options, in order of usefulness:

node -e "require('./package.json')" — uses Node.js itself; prints SyntaxError with line/column on failure.

npx jsonlint package.json — dedicated linter with readable diff-style output.

python3 -m json.tool package.json — works on any machine with Python 3; no install needed.

ERR_INVALID_PACKAGE_CONFIG with pnpm or yarn clean install fix

The same clean-reinstall fix applies for pnpm and Yarn. For pnpm: rm -rf node_modules && pnpm store prune && pnpm install. For Yarn Classic: rm -rf node_modules yarn.lock && yarn cache clean && yarn install. For Yarn Berry (PnP): yarn cache clean && yarn install. The error almost always means a corrupted or partially written package.json inside the store or node_modules directory.

Does ERR_INVALID_PACKAGE_CONFIG only affect ESM projects?

No. While the exports field is most commonly used in ESM-aware packages, ERR_INVALID_PACKAGE_CONFIG is thrown for both require() (CommonJS) and import (ESM) when Node.js resolves a module and encounters an invalid package.json on the resolution path. A malformed JSON file in a CJS-only project will trigger the error just as quickly.

What Node.js versions enforce ERR_INVALID_PACKAGE_CONFIG?

The exports and imports field validation was introduced in Node.js 12.7 (unflagged in 12.17). Structural validation has tightened with every major Node.js release. Node.js 14+ enforces the no-mixed-keys rule for exports. Node.js 22 applies the strictest checks currently available. Node.js versions before 12.7 ignore the exports field entirely and would not throw this error for exports-related issues (but would still throw for malformed JSON).

Related Errors