Skip to content

Shell tool injects NODE_ENV=production into every spawned command, breaking dev/test tooling #971

Description

@ahmedgamalalzatary

Summary

Environment

- Command Code on Windows (win32)
- Shell tool: PowerShell 5.1
- NODE_ENV not set at Machine or User scope

## Problem
Every command executed through the shell/powershell tool runs with
`NODE_ENV=production`, even though the user's own shell has it unset.
This causes commands to fail in the tool that succeed in the user's
terminal.

## Reproduction
Check the value in any shell tool call:

    $env:NODE_ENV
    # -> production

Then check where it comes from:

    [Environment]::GetEnvironmentVariable('NODE_ENV','Machine')  # -> empty
    [Environment]::GetEnvironmentVariable('NODE_ENV','User')     # -> empty
    [Environment]::GetEnvironmentVariable('NODE_ENV','Process')  # -> production

## Root cause
`NODE_ENV` is present at **Process** scope only. Machine and User scopesare both empty, so it is not inherited from the Windows environment

or
from a shell profile — it is injected into the environment whenCommand Code spawns the shell process.

## Impact
Tooling reads `NODE_ENV` to decide dev vs. prod behavior. With it pinned
to `production`, commands that work in the user's terminal fail or behave
differently:

- **npm/pnpm/yarn skip `devDependencies`** on install, so build/test/lint
  binaries (vitest, eslint, tsx, typescript) are missing -> "command not found"
  or unresolved imports
- **Vite** switches to production optimization paths, dropping
  `NODE_ENV === 'development'` branches, dev-only warnings, and HMR wiring
- **react-refresh / ts-node / nodemon** change transpilation and reload behavior
- Test runs may execute production-only code paths

## ScopeThis affects only subprocesses spawned by the shell tool. The user's
interactive shell is unaffected (`NODE_ENV` is genuinely unset there).
The asymmetry is the confusing part: the same command works for the user
and fails for the agent, with no visible difference in the command itself.

Expected Behavior

Expected behavior

The shell tool should not inject `NODE_ENV=production` into spawned
commands. Either:
- don't set it at all, letting the user/system environment pass through, or
- make it opt-in / configurable per session

## Additional context
Verified in a live session: `NODE_ENV=production` at process scope,
empty at machine and user scope.

Actual Behavior

The shell tool spawns every command with NODE_ENV=production in its environment.

Evidence, in three scopes:

[Environment]::GetEnvironmentVariable('NODE_ENV','Machine') -> empty
[Environment]::GetEnvironmentVariable('NODE_ENV','User') -> empty
[Environment]::GetEnvironmentVariable('NODE_ENV','Process') -> production

NODE_ENV exists at Process scope only. Since Machine and User are both empty, it is not inherited from Windows or from a shell profile —
Command Code injects it when spawning the shell.

Meanwhile the user's own shell has NODE_ENV genuinely unset, so the same command can work for them and fail inside the tool with no visible
difference between the two.

Steps to reproduce the issue

Confirm the variable is injected:

  1. Open any session with the shell tool on Windows.

  2. Run: $env:NODE_ENV

  3. Observe: production.

Confirm the origin is the tool, not the system:

  1. Run: [Environment]::GetEnvironmentVariable('NODE_ENV','Machine')
    [Environment]::GetEnvironmentVariable('NODE_ENV','User')
    [Environment]::GetEnvironmentVariable('NODE_ENV','Process')
  2. Observe: first two empty, third production.

Confirm the asymmetry:

  1. Run $env:NODE_ENV in your own PowerShell window outside the session.
  2. Observe: empty. Same machine, same account, different result.

Expected: no NODE_ENV set, matching the user's environment.

Command Code Version

1.73.2

Operating System

Windows

Terminal/IDE

Unknown

Shell

cmd.exe

Session file (optional)

No response

Fix prompt (optional)

No response

Additional context

No response

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions