fix(engine): emit SystemMemory cgroup notice to stderr, not stdout#2520
Merged
Conversation
vanceingalls
approved these changes
Jul 16, 2026
vanceingalls
left a comment
Collaborator
There was a problem hiding this comment.
RIGHT direction — approve. Root fix at the right layer: flip the SystemMemory cgroup diagnostic from stdout (console.info) to stderr (console.warn), aligning it with the sibling warnCgroupReadFailure in the same file. Every --json-emitting CLI benefits without further wiring.
Strengths
packages/engine/src/services/systemMemory.ts:96-100— inline comment on why (check --jsonpayload, Video Agent parse breakage) means the invariant lives with the log site, not just in this PR body. Future edits are unlikely to reintroduce the drift.packages/engine/src/services/systemMemory.test.ts:255-272— positive-and-negative pin (assertswarncalled once with the notice, ANDinfo/logNOT called). Guards against a re-drift to stdout even if someone re-addsconsole.infoorconsole.logon the detected-limit branch.- Ground-truth alignment:
packages/cli/src/commands/check.ts:118-136confirms--jsonwrites the machine-readable envelope viaconsole.log(stdout) and the non-JSON banner is already gated by!asJson. The bug was exactly the described stream collision. - Ground-truth cleanliness:
rg -n "console\.info" packages/engine packages/cliat head returns only the site this PR flips — no siblingconsole.infowas left behind for a future rework cycle.
Verified premises
- Sibling
warnCgroupReadFailureatsystemMemory.ts:140-148already usesconsole.warn. Convention exists; this PR aligns the outlier. - No other tests depend on the notice text; no
console.infospies inpackages/engine. Change is fully isolated. - CI: all required checks green at
87327381c56c31c298fe53c76cd025bb6b05cb3f(CLI smoke required, Test, Windows, Fallow, Format, Lint, Typecheck, Build).regression-shardspending — a stdout-vs-stderr stream flip on a diagnostic log doesn't touch rendering, so those shards are non-shape-related to the merge decision.
Nits (non-blocking, optional)
- nit —
packages/engine/AGENTS.md(or the closest package convention doc) could carry a one-line rule: "engine diagnostics useconsole.warn; stdout is reserved for CLI data payloads." The inline comment gets us most of the way; a docs echo makes the convention discoverable via grep instead of by finding this file. Would prevent the next contributor from addingconsole.infosomewhere new. - nit — the comment mentions the Video Agent parse specifically; if the incident has a ticket / Datadog link, threading it inline would help the next debugger who greps for the failure signature. Not blocking.
Verdict: APPROVE
Reasoning: One-line stream flip at the right layer, positive+negative test pin, no sibling drift, sibling function already established the stderr convention, and the merge-gate blocker is REVIEW_REQUIRED only.
— Via
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Emit the
[SystemMemory] cgroup memory limit detected: ...notice withconsole.warn(stderr) instead ofconsole.info(stdout) inpackages/engine/src/services/systemMemory.ts.Why
The
check --jsoncommand writes its machine-readable envelope to stdout viaconsole.log. This SystemMemory notice was also going to stdout (console.info), so on any host with a cgroup memory limit it prepended a non-JSON line ahead of the--jsonpayload and broke consumers that parse stdout as JSON. Standard CLI practice: stdout carries the data payload, diagnostics go to stderr. The sibling "unable to read cgroup" warning already usesconsole.warn(stderr); this aligns the detected-limit notice with it.How
One-line change:
console.info(...)→console.warn(...)for the detected-limit notice. Message text and all memory-adaptive behaviour are unchanged — only the stream moves from stdout to stderr.dist/is gitignored, so there is no built artifact to update.Test plan
Added a regression test in
packages/engine/src/services/systemMemory.test.tsasserting the detected-limit notice is emitted onconsole.warnand NOT onconsole.info/console.log, socheck --jsonstdout stays machine-parseable.bunx vitest run src/services/systemMemory.test.ts→ 27 passed (vitest labels the notice output as stderr)oxfmt+oxlinton both changed files → cleanUnit tests added/updated
Manual testing performed
Documentation updated (if applicable)