Skip to content
Latchkey

npm Scripts - Environment Variable Not Expanding (Cross-Platform) in CI

npm scripts run in a shell, and variable-expansion syntax differs between shells/OSes. A script that sets or reads a variable with the wrong syntax ends up with the literal token instead of its value.

What this error means

A build behaves as if an env var is unset, or logs show a literal $VAR/%VAR%. Often the script sets NODE_ENV=production cmd (works on POSIX) but runs on Windows, or uses $VAR where the shell does not expand it.

npm output
> app@1.0.0 build
> NODE_ENV=production webpack

'NODE_ENV' is not recognized as an internal or external command,
operable program or batch file.

Common causes

POSIX inline env syntax on Windows

VAR=value cmd is POSIX shell syntax. On Windows cmd it is not understood, so the variable is not set and the command errors or runs without it.

Wrong expansion token for the shell

Using %VAR% in bash or $VAR in cmd yields the literal text because each shell expands differently.

How to fix it

Set env vars cross-platform with cross-env

Use cross-env so the same script works on every OS.

package.json
// package.json
"scripts": {
  "build": "cross-env NODE_ENV=production webpack"
}

Standardize the CI shell

  1. Pin a single shell in CI (e.g. bash) so expansion is predictable.
  2. Pass values via the job env: block instead of inline shell syntax where possible.
  3. Avoid mixing %VAR% and $VAR styles in scripts.

How to prevent it

  • Use cross-env for inline env vars in package scripts.
  • Set a consistent CI shell.
  • Prefer the workflow env block over shell-specific syntax.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →