Skip to content

fix(core): preserve FORCE_COLOR=0 intent for forked child tasks#35293

Open
comp615 wants to merge 1 commit intonrwl:masterfrom
comp615:fix/force-color-propagation
Open

fix(core): preserve FORCE_COLOR=0 intent for forked child tasks#35293
comp615 wants to merge 1 commit intonrwl:masterfrom
comp615:fix/force-color-propagation

Conversation

@comp615
Copy link
Copy Markdown
Contributor

@comp615 comp615 commented Apr 14, 2026

Note: An alternative to this PR is to wait for the upstream picocolors#100 fix and then remove the FORCE_COLOR=0 workaround in bin/nx.ts entirely. However, picocolors has not had a release or meaningful activity in over two years and appears to be unmaintained, so this fix ensures correct behavior in the meantime.

Current Behavior

When FORCE_COLOR=0 is set (common in CI to suppress ANSI codes), bin/nx.ts deletes it from process.env as a workaround for picocolors#100. However, task-env.ts and task-orchestrator.ts then default the undefined FORCE_COLOR to 'true' for all forked child tasks, re-enabling ANSI colors in every child process.

User sets FORCE_COLOR=0
  → bin/nx.ts deletes FORCE_COLOR, sets NO_COLOR=1
  → task-env.ts sees FORCE_COLOR === undefined → defaults to 'true'
  → child processes receive FORCE_COLOR=true (overrides NO_COLOR)
  → ANSI escape codes in ESLint, TypeScript, Vitest output

Expected Behavior

FORCE_COLOR=0 should propagate to child tasks, resulting in no ANSI escape codes.

Solution

  1. bin/nx.ts: Save the original value in NX_ORIGINAL_FORCE_COLOR before deleting
  2. task-env.ts: Extract a getForceColorForChild() helper that checks NX_ORIGINAL_FORCE_COLOR when FORCE_COLOR is undefined
  3. task-orchestrator.ts: Use the shared helper at both call sites

Impact

This affects any CI environment that sets FORCE_COLOR=0. In our case, ANSI escape codes in ESLint output broke downstream log parsers that use regex to extract lint errors (the ✖ N problems summary line contains invisible ANSI bytes that prevent matching).

Tests

Added 4 unit tests for getForceColorForChild() covering:

  • Explicit FORCE_COLOR passthrough
  • FORCE_COLOR=0 → deleted → restored via NX_ORIGINAL_FORCE_COLOR
  • Default to 'true' when neither is set
  • FORCE_COLOR takes precedence over NX_ORIGINAL_FORCE_COLOR

Fixes #35292

🤖 This PR was drafted with the help of AI

@comp615 comp615 requested a review from a team as a code owner April 14, 2026 15:02
@comp615 comp615 requested a review from leosvelperez April 14, 2026 15:02
@netlify
Copy link
Copy Markdown

netlify Bot commented Apr 14, 2026

👷 Deploy request for nx-docs pending review.

Visit the deploys page to approve it

Name Link
🔨 Latest commit 54d893b

@netlify
Copy link
Copy Markdown

netlify Bot commented Apr 14, 2026

👷 Deploy request for nx-dev pending review.

Visit the deploys page to approve it

Name Link
🔨 Latest commit 54d893b

@comp615 comp615 force-pushed the fix/force-color-propagation branch from a314699 to 901bd05 Compare April 14, 2026 15:13
@comp615
Copy link
Copy Markdown
Contributor Author

comp615 commented Apr 14, 2026

@FrozenPandaz FYI

Also note that I think it might be OK if force-color true wasn't set in CI

@AgentEnder AgentEnder force-pushed the fix/force-color-propagation branch from 901bd05 to 4bcdfac Compare April 17, 2026 04:27
@nx-cloud
Copy link
Copy Markdown
Contributor

nx-cloud Bot commented Apr 17, 2026

View your CI Pipeline Execution ↗ for commit 54d893b

Command Status Duration Result
nx affected --targets=lint,test,build,e2e,e2e-c... ❌ Failed 41m 50s View ↗
nx run-many -t check-imports check-lock-files c... ✅ Succeeded 3s View ↗
nx-cloud record -- pnpm nx-cloud conformance:check ✅ Succeeded 16s View ↗
nx build workspace-plugin ✅ Succeeded 2m 36s View ↗
nx-cloud record -- nx sync:check ✅ Succeeded 21s View ↗
nx-cloud record -- nx format:check ✅ Succeeded 6s View ↗

☁️ Nx Cloud last updated this comment at 2026-04-27 21:52:20 UTC

@FrozenPandaz FrozenPandaz requested a review from AgentEnder April 23, 2026 20:54
@FrozenPandaz FrozenPandaz added the priority: medium Medium Priority (not high, not low priority) label Apr 23, 2026
@AgentEnder AgentEnder force-pushed the fix/force-color-propagation branch from 853ca44 to a5e24bb Compare April 25, 2026 00:17
nx-cloud[bot]

This comment was marked as outdated.

@AgentEnder AgentEnder force-pushed the fix/force-color-propagation branch from a5e24bb to d8dfb3d Compare April 25, 2026 00:38
nx-cloud[bot]

This comment was marked as outdated.

When FORCE_COLOR=0 is set in the environment, bin/nx.ts deletes it
(workaround for picocolors treating '0' as truthy). However, task-env.ts
and task-orchestrator.ts then default the undefined FORCE_COLOR to 'true'
for all forked children, re-enabling ANSI colors.

Save the original FORCE_COLOR value in NX_ORIGINAL_FORCE_COLOR before
deleting, and consult it when building child process environments.
Extract the logic into a shared getForceColorForChild() helper.

Fixes nrwl#35292

Co-authored-by: Amp <amp@ampcode.com>
Amp-Thread-ID: https://ampcode.com/threads/T-019d8c4e-0d90-7126-b438-be77211ef603
@AgentEnder AgentEnder force-pushed the fix/force-color-propagation branch from d8dfb3d to 54d893b Compare April 27, 2026 20:44
Copy link
Copy Markdown
Contributor

@nx-cloud nx-cloud Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nx Cloud has identified a possible root cause for your failed CI:

This CI failure appears to be related to the environment or external dependencies rather than your code changes.

No code changes were suggested for this issue.

You can trigger a rerun by pushing an empty commit:

git commit --allow-empty -m "chore: trigger rerun"
git push

Nx Cloud View detailed reasoning on Nx Cloud ↗

🔔 Heads up, your workspace has pending recommendations ↗ to auto-apply fixes for similar failures.


🎓 Learn more about Self-Healing CI on nx.dev

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

Labels

priority: medium Medium Priority (not high, not low priority)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

FORCE_COLOR=0 is deleted then re-introduced as 'true' for forked child tasks

3 participants