Skip to content

fix: warnings in store|config should be printed to stderr#12434

Merged
zkochan merged 2 commits into
pnpm:mainfrom
felipecrs:print-store-warnings-to-stderr
Jun 16, 2026
Merged

fix: warnings in store|config should be printed to stderr#12434
zkochan merged 2 commits into
pnpm:mainfrom
felipecrs:print-store-warnings-to-stderr

Conversation

@felipecrs

@felipecrs felipecrs commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Closes #12432

Summary by CodeRabbit

  • Bug Fixes
    • Updated reporter output for the store command so warnings/progress are sent to stderr instead of stdout, avoiding contamination of captured output in automation.
    • Extended the same stdout/stderr reporter routing to config-related subcommands (config, set, get) for consistent behavior.

@felipecrs felipecrs requested a review from zkochan as a code owner June 15, 2026 21:10
Copilot AI review requested due to automatic review settings June 15, 2026 21:10
@welcome

welcome Bot commented Jun 15, 2026

Copy link
Copy Markdown

💖 Thanks for opening this pull request! 💖
Please be patient and we will get back to you as soon as we can.

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Jun 15, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (0) 📎 Requirement gaps (1)

Context used

Grey Divider


Action required

1. run missing useStderr 📎 Requirement gap ≡ Correctness
Description
The override deprecation warning is emitted via globalWarn() and will be printed by the
default/append-only reporter to stdout unless config.useStderr is enabled. main() only enables
useStderr for a small set of commands, so pnpm build (parsed as cmd === 'run') can still
contaminate stdout with the override deprecation warning and break scripts/tooling that consume
stdout.
Code

pnpm/src/main.ts[R144-145]

+    if (isDlxOrCreateCommand || isConfigCommand || cmd === 'sbom' || cmd === 'with' || cmd === 'store') {
     config.useStderr = true
Evidence
Compliance requires the override deprecation warning not to appear on stdout, but main() still
leaves useStderr disabled for cmd === 'run' (used by pnpm build), and the reporter writes
warnings to stdout when useStderr is false. The override deprecation warning itself is emitted
via globalWarn() when overrides use $ references, so it can still reach stdout for run-based
invocations.

Do not print override deprecation warnings to stdout during pnpm invocation
Ensure pnpm scripts are not broken by repeated warning output on each command execution
pnpm/src/main.ts[137-146]
pnpm/src/parseCliArgs.ts[19-33]
config/reader/src/getOptionsFromRootManifest.ts[51-60]
config/reader/src/getOptionsFromRootManifest.ts[141-148]
cli/default-reporter/src/index.ts[52-56]
cli/default-reporter/src/index.ts[80-83]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`config.useStderr` is not enabled for `cmd === 'run'` (the fallback command used by `pnpm <script>` such as `pnpm build`). As a result, the override deprecation warning emitted via `globalWarn()` can still be routed to `stdout`, violating the requirement that warnings must not corrupt `stdout`.
## Issue Context
- The override deprecation warning is emitted in the config reader via `globalWarn()`.
- The default/append-only reporter writes to `proc.stdout` unless `useStderr` is set.
- `pnpm build` is parsed as `cmd === 'run'` via `fallbackCommand: 'run'`.
## Fix Focus Areas
- pnpm/src/main.ts[137-146]
- pnpm/src/parseCliArgs.ts[19-33]
- config/reader/src/getOptionsFromRootManifest.ts[51-60]
- cli/default-reporter/src/index.ts[52-56]
- cli/default-reporter/src/index.ts[80-83]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Wrong TTY stream checked 🐞 Bug ☼ Reliability
Description
After enabling config.useStderr for pnpm store/pnpm config, reporter selection still checks
process.stdout.isTTY, so the interactive (ansi-diff) reporter may be chosen even when stderr is
redirected, producing control-sequence garbage in stderr logs/files.
Code

pnpm/src/main.ts[R144-145]

+    if (isDlxOrCreateCommand || isConfigCommand || cmd === 'sbom' || cmd === 'with' || cmd === 'store') {
    config.useStderr = true
Evidence
The PR change routes reporter output to stderr for store/config, but reporterType is still
computed from stdout’s TTY state. The default reporter’s non-append-only path uses ansi-diff and
writes via proc.stderr.write when useStderr is true, so if stderr is redirected while stdout
remains a TTY, ANSI diff sequences get written into the redirected stderr stream.

pnpm/src/main.ts[137-146]
pnpm/src/main.ts[186-191]
cli/default-reporter/src/index.ts[43-89]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`config.useStderr` is now enabled for `store` and `config` entrypoints, but `reporterType` selection still uses `process.stdout.isTTY`. When stdout is a TTY and stderr is redirected to a file/pipe, pnpm may still choose the default interactive reporter and write `ansi-diff` control sequences into redirected stderr.
### Issue Context
- `config.useStderr` changes the stream used by the default reporter (`proc.stderr.write(...)`).
- The interactive reporter path uses `ansi-diff` (`diff.update(...)`), which is only appropriate for TTY output.
### Fix Focus Areas
- pnpm/src/main.ts[186-191]
- cli/default-reporter/src/index.ts[43-89]
### Suggested fix
1. In `pnpm/src/main.ts`, select `reporterType` using the TTY status of the actual reporter output stream:
- Determine `const reporterStream = config.useStderr ? process.stderr : process.stdout`
- Use `!reporterStream.isTTY` (instead of `!process.stdout.isTTY`) when deciding `'append-only'` vs `'default'`.
2. (Optional but consistent) In `cli/default-reporter/src/index.ts`, compute `outputMaxWidth` and `height` from the same stream the reporter writes to (stderr when `useStderr` is true), not always from `proc.stdout`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. stderr EPIPE can crash 🐞 Bug ☼ Reliability
Description
main() now forces config.useStderr=true for pnpm store, so the default reporter writes to
process.stderr, but the CLI only installs an EPIPE handler for process.stdout. If stderr is
piped and the reader closes early (e.g. 2> >(head -n 1)), an unhandled EPIPE during reporter
output can terminate the command.
Code

pnpm/src/main.ts[R143-145]

+    if (isDlxOrCreateCommand || cmd === 'sbom' || cmd === 'with' || cmd === 'store') {
   config.useStderr = true
 }
Evidence
The PR change enables useStderr for store, which routes reporter writes to proc.stderr.write,
but only stdout has an EPIPE error handler, leaving stderr writes unprotected in the same scenario
stdout was explicitly protected for.

pnpm/src/main.ts[45-52]
pnpm/src/main.ts[140-145]
cli/default-reporter/src/index.ts[80-82]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`pnpm/src/main.ts` installs an `EPIPE` handler only for `process.stdout`, but this PR makes `pnpm store` reporter output go to `process.stderr` (`config.useStderr = true`). When stderr is piped and the downstream reader closes early, writes to `process.stderr` may raise `EPIPE` and crash the process.
### Issue Context
The default reporter selects `proc.stderr.write` when `useStderr` is enabled. With this PR, `pnpm store` opts into that path.
### Fix Focus Areas
- pnpm/src/main.ts[45-52]
- pnpm/src/main.ts[143-145]
- cli/default-reporter/src/index.ts[80-82]
### Suggested fix
Add the same `EPIPE` suppression handler for `process.stderr` as exists for `process.stdout` (or refactor into a shared helper that attaches to both streams).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Previous review results

Review updated until commit a0faaeb

Results up to commit 311fe05


🐞 Bugs (2) 📘 Rule violations (0) 📎 Requirement gaps (1)

Context used

Action required
1. run missing useStderr 📎 Requirement gap ≡ Correctness ⭐ New
Description
The override deprecation warning is emitted via globalWarn() and will be printed by the
default/append-only reporter to stdout unless config.useStderr is enabled. main() only enables
useStderr for a small set of commands, so pnpm build (parsed as cmd === 'run') can still
contaminate stdout with the override deprecation warning and break scripts/tooling that consume
stdout.
Code

pnpm/src/main.ts[R144-145]

+    if (isDlxOrCreateCommand || isConfigCommand || cmd === 'sbom' || cmd === 'with' || cmd === 'store') {
      config.useStderr = true
Evidence
Compliance requires the override deprecation warning not to appear on stdout, but main() still
leaves useStderr disabled for cmd === 'run' (used by pnpm build), and the reporter writes
warnings to stdout when useStderr is false. The override deprecation warning itself is emitted
via globalWarn() when overrides use $ references, so it can still reach stdout for run-based
invocations.

Do not print override deprecation warnings to stdout during pnpm invocation
Ensure pnpm scripts are not broken by repeated warning output on each command execution
pnpm/src/main.ts[137-146]
pnpm/src/parseCliArgs.ts[19-33]
config/reader/src/getOptionsFromRootManifest.ts[51-60]
config/reader/src/getOptionsFromRootManifest.ts[141-148]
cli/default-reporter/src/index.ts[52-56]
cli/default-reporter/src/index.ts[80-83]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`config.useStderr` is not enabled for `cmd === 'run'` (the fallback command used by `pnpm <script>` such as `pnpm build`). As a result, the override deprecation warning emitted via `globalWarn()` can still be routed to `stdout`, violating the requirement that warnings must not corrupt `stdout`.

## Issue Context
- The override deprecation warning is emitted in the config reader via `globalWarn()`.
- The default/append-only reporter writes to `proc.stdout` unless `useStderr` is set.
- `pnpm build` is parsed as `cmd === 'run'` via `fallbackCommand: 'run'`.

## Fix Focus Areas
- pnpm/src/main.ts[137-146]
- pnpm/src/parseCliArgs.ts[19-33]
- config/reader/src/getOptionsFromRootManifest.ts[51-60]
- cli/default-reporter/src/index.ts[52-56]
- cli/default-reporter/src/index.ts[80-83]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended
2. Wrong TTY stream checked 🐞 Bug ☼ Reliability
Description
After enabling config.useStderr for pnpm store/pnpm config, reporter selection still checks
process.stdout.isTTY, so the interactive (ansi-diff) reporter may be chosen even when stderr is
redirected, producing control-sequence garbage in stderr logs/files.
Code

pnpm/src/main.ts[R144-145]

+    if (isDlxOrCreateCommand || isConfigCommand || cmd === 'sbom' || cmd === 'with' || cmd === 'store') {
     config.useStderr = true
Evidence
The PR change routes reporter output to stderr for store/config, but reporterType is still
computed from stdout’s TTY state. The default reporter’s non-append-only path uses ansi-diff and
writes via proc.stderr.write when useStderr is true, so if stderr is redirected while stdout
remains a TTY, ANSI diff sequences get written into the redirected stderr stream.

pnpm/src/main.ts[137-146]
pnpm/src/main.ts[186-191]
cli/default-reporter/src/index.ts[43-89]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`config.useStderr` is now enabled for `store` and `config` entrypoints, but `reporterType` selection still uses `process.stdout.isTTY`. When stdout is a TTY and stderr is redirected to a file/pipe, pnpm may still choose the default interactive reporter and write `ansi-diff` control sequences into redirected stderr.
### Issue Context
- `config.useStderr` changes the stream used by the default reporter (`proc.stderr.write(...)`).
- The interactive reporter path uses `ansi-diff` (`diff.update(...)`), which is only appropriate for TTY output.
### Fix Focus Areas
- pnpm/src/main.ts[186-191]
- cli/default-reporter/src/index.ts[43-89]
### Suggested fix
1. In `pnpm/src/main.ts`, select `reporterType` using the TTY status of the actual reporter output stream:
 - Determine `const reporterStream = config.useStderr ? process.stderr : process.stdout`
 - Use `!reporterStream.isTTY` (instead of `!process.stdout.isTTY`) when deciding `'append-only'` vs `'default'`.
2. (Optional but consistent) In `cli/default-reporter/src/index.ts`, compute `outputMaxWidth` and `height` from the same stream the reporter writes to (stderr when `useStderr` is true), not always from `proc.stdout`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. stderr EPIPE can crash 🐞 Bug ☼ Reliability
Description
main() now forces config.useStderr=true for pnpm store, so the default reporter writes to
process.stderr, but the CLI only installs an EPIPE handler for process.stdout. If stderr is
piped and the reader closes early (e.g. 2> >(head -n 1)), an unhandled EPIPE during reporter
output can terminate the command.
Code

pnpm/src/main.ts[R143-145]

+    if (isDlxOrCreateCommand || cmd === 'sbom' || cmd === 'with' || cmd === 'store') {
    config.useStderr = true
  }
Evidence
The PR change enables useStderr for store, which routes reporter writes to proc.stderr.write,
but only stdout has an EPIPE error handler, leaving stderr writes unprotected in the same scenario
stdout was explicitly protected for.

pnpm/src/main.ts[45-52]
pnpm/src/main.ts[140-145]
cli/default-reporter/src/index.ts[80-82]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`pnpm/src/main.ts` installs an `EPIPE` handler only for `process.stdout`, but this PR makes `pnpm store` reporter output go to `process.stderr` (`config.useStderr = true`). When stderr is piped and the downstream reader closes early, writes to `process.stderr` may raise `EPIPE` and crash the process.
### Issue Context
The default reporter selects `proc.stderr.write` when `useStderr` is enabled. With this PR, `pnpm store` opts into that path.
### Fix Focus Areas
- pnpm/src/main.ts[45-52]
- pnpm/src/main.ts[143-145]
- cli/default-reporter/src/index.ts[80-82]
### Suggested fix
Add the same `EPIPE` suppression handler for `process.stderr` as exists for `process.stdout` (or refactor into a shared helper that attaches to both streams).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Results up to commit c60414d


🐞 Bugs (2) 📘 Rule violations (0) 📎 Requirement gaps (0)

Context used

Remediation recommended
1. Wrong TTY stream checked 🐞 Bug ☼ Reliability ⭐ New
Description
After enabling config.useStderr for pnpm store/pnpm config, reporter selection still checks
process.stdout.isTTY, so the interactive (ansi-diff) reporter may be chosen even when stderr is
redirected, producing control-sequence garbage in stderr logs/files.
Code

pnpm/src/main.ts[R144-145]

+    if (isDlxOrCreateCommand || isConfigCommand || cmd === 'sbom' || cmd === 'with' || cmd === 'store') {
      config.useStderr = true
Evidence
The PR change routes reporter output to stderr for store/config, but reporterType is still
computed from stdout’s TTY state. The default reporter’s non-append-only path uses ansi-diff and
writes via proc.stderr.write when useStderr is true, so if stderr is redirected while stdout
remains a TTY, ANSI diff sequences get written into the redirected stderr stream.

pnpm/src/main.ts[137-146]
pnpm/src/main.ts[186-191]
cli/default-reporter/src/index.ts[43-89]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`config.useStderr` is now enabled for `store` and `config` entrypoints, but `reporterType` selection still uses `process.stdout.isTTY`. When stdout is a TTY and stderr is redirected to a file/pipe, pnpm may still choose the default interactive reporter and write `ansi-diff` control sequences into redirected stderr.

### Issue Context
- `config.useStderr` changes the stream used by the default reporter (`proc.stderr.write(...)`).
- The interactive reporter path uses `ansi-diff` (`diff.update(...)`), which is only appropriate for TTY output.

### Fix Focus Areas
- pnpm/src/main.ts[186-191]
- cli/default-reporter/src/index.ts[43-89]

### Suggested fix
1. In `pnpm/src/main.ts`, select `reporterType` using the TTY status of the actual reporter output stream:
  - Determine `const reporterStream = config.useStderr ? process.stderr : process.stdout`
  - Use `!reporterStream.isTTY` (instead of `!process.stdout.isTTY`) when deciding `'append-only'` vs `'default'`.
2. (Optional but consistent) In `cli/default-reporter/src/index.ts`, compute `outputMaxWidth` and `height` from the same stream the reporter writes to (stderr when `useStderr` is true), not always from `proc.stdout`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. stderr EPIPE can crash 🐞 Bug ☼ Reliability
Description
main() now forces config.useStderr=true for pnpm store, so the default reporter writes to
process.stderr, but the CLI only installs an EPIPE handler for process.stdout. If stderr is
piped and the reader closes early (e.g. 2> >(head -n 1)), an unhandled EPIPE during reporter
output can terminate the command.
Code

pnpm/src/main.ts[R143-145]

+    if (isDlxOrCreateCommand || cmd === 'sbom' || cmd === 'with' || cmd === 'store') {
     config.useStderr = true
   }
Evidence
The PR change enables useStderr for store, which routes reporter writes to proc.stderr.write,
but only stdout has an EPIPE error handler, leaving stderr writes unprotected in the same scenario
stdout was explicitly protected for.

pnpm/src/main.ts[45-52]
pnpm/src/main.ts[140-145]
cli/default-reporter/src/index.ts[80-82]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`pnpm/src/main.ts` installs an `EPIPE` handler only for `process.stdout`, but this PR makes `pnpm store` reporter output go to `process.stderr` (`config.useStderr = true`). When stderr is piped and the downstream reader closes early, writes to `process.stderr` may raise `EPIPE` and crash the process.
### Issue Context
The default reporter selects `proc.stderr.write` when `useStderr` is enabled. With this PR, `pnpm store` opts into that path.
### Fix Focus Areas
- pnpm/src/main.ts[45-52]
- pnpm/src/main.ts[143-145]
- cli/default-reporter/src/index.ts[80-82]
### Suggested fix
Add the same `EPIPE` suppression handler for `process.stderr` as exists for `process.stdout` (or refactor into a shared helper that attaches to both streams).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Results up to commit 403526e


🐞 Bugs (1) 📘 Rule violations (0) 📎 Requirement gaps (0)

Context used

Remediation recommended
1. stderr EPIPE can crash 🐞 Bug ☼ Reliability
Description
main() now forces config.useStderr=true for pnpm store, so the default reporter writes to
process.stderr, but the CLI only installs an EPIPE handler for process.stdout. If stderr is
piped and the reader closes early (e.g. 2> >(head -n 1)), an unhandled EPIPE during reporter
output can terminate the command.
Code

pnpm/src/main.ts[R143-145]

+    if (isDlxOrCreateCommand || cmd === 'sbom' || cmd === 'with' || cmd === 'store') {
      config.useStderr = true
    }
Evidence
The PR change enables useStderr for store, which routes reporter writes to proc.stderr.write,
but only stdout has an EPIPE error handler, leaving stderr writes unprotected in the same scenario
stdout was explicitly protected for.

pnpm/src/main.ts[45-52]
pnpm/src/main.ts[140-145]
cli/default-reporter/src/index.ts[80-82]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`pnpm/src/main.ts` installs an `EPIPE` handler only for `process.stdout`, but this PR makes `pnpm store` reporter output go to `process.stderr` (`config.useStderr = true`). When stderr is piped and the downstream reader closes early, writes to `process.stderr` may raise `EPIPE` and crash the process.

### Issue Context
The default reporter selects `proc.stderr.write` when `useStderr` is enabled. With this PR, `pnpm store` opts into that path.

### Fix Focus Areas
- pnpm/src/main.ts[45-52]
- pnpm/src/main.ts[143-145]
- cli/default-reporter/src/index.ts[80-82]

### Suggested fix
Add the same `EPIPE` suppression handler for `process.stderr` as exists for `process.stdout` (or refactor into a shared helper that attaches to both streams).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Results up to commit N/A


New Review Started


This review has been superseded by a new analysis


Qodo Logo

@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The store command is added to the predicate in main.ts that sets config.useStderr = true, routing its reporter output to stderr instead of stdout. A changeset entry documents the fix for pnpm store path command substitution in scripts.

Changes

store command stderr routing

Layer / File(s) Summary
Add store to useStderr predicate
.changeset/store-use-stderr.md, pnpm/src/main.ts
The changeset documents that pnpm store and pnpm config reporter output now goes to stderr. An isConfigCommand flag is introduced for config command detection. The useStderr predicate is extended to include cmd === 'store' alongside existing dlx/create, sbom, and with commands.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~2 minutes

Suggested reviewers

  • zkochan

Poem

🐇 Hop hop, the store has learned to speak
Into stderr, not stdout's creek.
$(pnpm store path) stands pure and bright,
No warnings muddled in the script's delight.
A single line changed, the fix complete! 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly and accurately summarizes the main change: routing warnings from store and config commands to stderr instead of stdout.
Linked Issues check ✅ Passed The code changes directly address issue #12432 by implementing stderr routing for warnings in store and config commands, preventing stdout contamination in scripts.
Out of Scope Changes check ✅ Passed All changes are scoped to fixing the stdout/stderr routing issue for store and config commands with no unrelated modifications present.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR routes reporter output for the pnpm store command to stderr so that the stdout output (notably pnpm store path) can be safely captured in scripts without warnings/noise.

Changes:

  • Add store to the list of commands that force config.useStderr = true
  • Add a changeset documenting the behavior change for pnpm store path / store output streams

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
pnpm/src/main.ts Forces stderr reporter output for the store command by setting config.useStderr
.changeset/store-use-stderr.md Adds release note describing the stdout/stderr behavior change for pnpm store path

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .changeset/store-use-stderr.md Outdated
Comment thread pnpm/src/main.ts Outdated
@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Jun 15, 2026

Copy link
Copy Markdown

PR Summary by Qodo

Route pnpm store/config reporter warnings & progress to stderr
🐞 Bug fix 🕐 10-20 Minutes

Grey Divider

Walkthroughs

Description
• Send pnpm store and pnpm config|set|get reporter output to stderr to keep stdout clean.
• Reuse a single isConfigCommand guard for config-related behavior.
• Add a changeset documenting the behavioral change for scripting/automation.
Diagram
graph TD
  U([Shell / CI script]) --> M["pnpm/src/main.ts"] --> C{"Command\nclassification"} --> S["config.useStderr = true"] --> R["Reporter output"] --> E["stderr (warnings/progress)"]
  C -->|"other commands"| R --> O["stdout (command output)"]
Loading
High-Level Assessment

Setting config.useStderr at the CLI entrypoint for store and config-related commands is the simplest and most consistent fix: it avoids per-subcommand plumbing changes while ensuring stdout remains machine-readable for scripting. The refactor to isConfigCommand also reduces repetition and makes future command additions less error-prone.

Grey Divider

File Changes

Bug fix (1)
main.ts Enable stderr reporting for store and config-related commands +3/-2

Enable stderr reporting for store and config-related commands

• Adds an 'isConfigCommand' helper to centralize recognition of 'config|set|get'. Uses it to tolerate config dependency errors consistently and to set 'config.useStderr = true' for config-related commands and 'store', preventing reporter warnings/progress from contaminating captured stdout.

pnpm/src/main.ts


Documentation (1)
store-use-stderr.md Add changeset documenting stderr reporter behavior for store/config +5/-0

Add changeset documenting stderr reporter behavior for store/config

• Introduces a patch changeset describing that warnings/progress for 'pnpm store' and 'pnpm config' now go to stderr. Calls out scripting scenarios where clean stdout is required (e.g., command substitution and piping to 'jq').

.changeset/store-use-stderr.md


Grey Divider

Qodo Logo

@felipecrs felipecrs force-pushed the print-store-warnings-to-stderr branch from 6fedddc to 01ce930 Compare June 15, 2026 21:11
@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Jun 15, 2026

Copy link
Copy Markdown

Code Review by Qodo

Grey Divider

New Review Started

This review has been superseded by a new analysis

Grey Divider

Qodo Logo

Copilot AI review requested due to automatic review settings June 15, 2026 21:13
@felipecrs felipecrs force-pushed the print-store-warnings-to-stderr branch from 01ce930 to f766492 Compare June 15, 2026 21:13
@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Jun 15, 2026

Copy link
Copy Markdown

Code Review by Qodo

Grey Divider

New Review Started

This review has been superseded by a new analysis

Grey Divider

Qodo Logo

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

Comment thread pnpm/src/main.ts Outdated
@felipecrs felipecrs force-pushed the print-store-warnings-to-stderr branch from f766492 to 403526e Compare June 15, 2026 21:14
@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Jun 15, 2026

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 403526e

Comment thread pnpm/src/main.ts Outdated
@felipecrs felipecrs marked this pull request as draft June 15, 2026 21:31
@felipecrs felipecrs changed the title fix: warnings in pnpm store should be printed to stderr fix: warnings in store|config should be printed to stderr Jun 15, 2026
@felipecrs felipecrs force-pushed the print-store-warnings-to-stderr branch 2 times, most recently from ddbd73e to e730e1a Compare June 15, 2026 21:43
@felipecrs felipecrs marked this pull request as ready for review June 15, 2026 21:44
Copilot AI review requested due to automatic review settings June 15, 2026 21:44
@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Jun 15, 2026

Copy link
Copy Markdown

Code Review by Qodo

Grey Divider

New Review Started

This review has been superseded by a new analysis

Grey Divider

Qodo Logo

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

Comment thread .changeset/store-use-stderr.md Outdated
@felipecrs felipecrs force-pushed the print-store-warnings-to-stderr branch from e730e1a to c60414d Compare June 15, 2026 21:47
@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Jun 15, 2026

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit c60414d

Comment thread pnpm/src/main.ts Outdated
Copilot AI review requested due to automatic review settings June 16, 2026 13:19
@zkochan zkochan force-pushed the print-store-warnings-to-stderr branch from c60414d to 311fe05 Compare June 16, 2026 13:19

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Jun 16, 2026

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 311fe05

Comment thread pnpm/src/main.ts Outdated
Comment on lines 144 to 145
if (isDlxOrCreateCommand || isConfigCommand || cmd === 'sbom' || cmd === 'with' || cmd === 'store') {
config.useStderr = true

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. run missing usestderr 📎 Requirement gap ≡ Correctness

The override deprecation warning is emitted via globalWarn() and will be printed by the
default/append-only reporter to stdout unless config.useStderr is enabled. main() only enables
useStderr for a small set of commands, so pnpm build (parsed as cmd === 'run') can still
contaminate stdout with the override deprecation warning and break scripts/tooling that consume
stdout.
Agent Prompt
## Issue description
`config.useStderr` is not enabled for `cmd === 'run'` (the fallback command used by `pnpm <script>` such as `pnpm build`). As a result, the override deprecation warning emitted via `globalWarn()` can still be routed to `stdout`, violating the requirement that warnings must not corrupt `stdout`.

## Issue Context
- The override deprecation warning is emitted in the config reader via `globalWarn()`.
- The default/append-only reporter writes to `proc.stdout` unless `useStderr` is set.
- `pnpm build` is parsed as `cmd === 'run'` via `fallbackCommand: 'run'`.

## Fix Focus Areas
- pnpm/src/main.ts[137-146]
- pnpm/src/parseCliArgs.ts[19-33]
- config/reader/src/getOptionsFromRootManifest.ts[51-60]
- cli/default-reporter/src/index.ts[52-56]
- cli/default-reporter/src/index.ts[80-83]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Good catch — this is a real instance of the same bug class, but routing run/exec reporter output to stderr the simple way (adding them to the useStderr set) breaks more than it fixes.

When pnpm runs multiple scripts — recursive (-r), --parallel, or several scripts in one project — it captures each child's stdout and re-emits it through its own reporter. So flipping the reporter to stderr would send the actual script output (not just warnings) to stderr, breaking pnpm -r build > out.txt. I verified this: adding run/exec to the set fails 4 tests in pnpm/test/run.ts (recursive args echo, collapsed multi-script output, --parallel, --reporter-hide-prefix), all because the script output lands on the wrong stream.

Only the single-script/single-project case inherits the child stdio directly, so the boundary is "single vs. multiplexed run", not "recursive vs. not" — it can't be expressed cleanly in main.ts's command classification. The correct fix is to separate pnpm's own warnings (e.g. the override-deprecation notice) from multiplexed child output during runs, which is a larger reporter/logger change.

Deferring run/exec to a dedicated follow-up PR; keeping this one scoped to store/config.


Written by an agent (Claude Code, claude-opus-4-8).

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Jun 16, 2026

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit a0faaeb

@zkochan zkochan merged commit 13815ad into pnpm:main Jun 16, 2026
18 checks passed
@felipecrs felipecrs deleted the print-store-warnings-to-stderr branch June 16, 2026 17:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

pnpm@11.5.3 breaks scripts as it prints warnings to stdout

3 participants