CASE FILE#2702CRITFiled 2026-04-13

Keeping Error Streams Visible: Claude Code and 2>&1

Claude Code redirects stderr into stdout to suppress noisy error output. SSG blocks the redirect — hiding error streams makes debugging agent failures significantly harder.

Case ID
#2702
Severity
CRIT
Decision
BLOCK
Agent
Claude Code
Category
Shell Safety

Correction note (2026-10-13). The per-call timings and latency figures that appeared in this article had no benchmark behind them and were removed. Sample output in this article is illustrative, not a recorded run. The only published measurement is p50 0.39 ms and p99 1.91 ms (sigmashake-bench daemon-socket run, 2026-06-10, ssg 0.29.156, n=500). Sub-2 ms evaluation is a design target. ssg eval reads the tool call as JSON on stdin and has no --content, --content-file, --file or positional form.

Describe the task

Your build script produces noisy error output that clutters the terminal. Claude Code adds a redirect to clean up the output:

npm run build 2>&1 | grep "Error"

Or more aggressively, to silence errors entirely:

npm run build 2>/dev/null

When Claude Code operates autonomously, suppressing stderr means build errors, auth failures, and critical warnings are swallowed — they never appear in your logs or reach your monitoring. Silent failures are the hardest bugs to diagnose. SSG's no-stderr-redirect rule blocks the redirect.

# illustrative sample output
[BLOCK] bash › npm run build 2>&1 | grep "Error" — rule: no-stderr-redirect

Give SSG context

SSG evaluates Claude Code's shell commands via the claude_code_hook integration (MCP Server or PreToolUse hook).

Required context

rule no-stderr-redirect {
  enabled true
  priority 50
  severity warning
  DENY execution
  IF command CONTAINS "2>&1"
  OR command CONTAINS "2>/dev/null"
  MESSAGE "Suppressing stderr hides error output. Keep error streams separate for visibility."
}

Optional context

Switch to ASK if you want to allow the redirect with human confirmation:

rule confirm-stderr-redirect {
  enabled true
  priority 50
  severity info
  ASK execution
  IF command CONTAINS "2>&1"
  OR command CONTAINS "2>/dev/null"
  PROMPT "This command redirects or suppresses stderr. Confirm this is intentional?"
  MESSAGE "This command redirects or suppresses stderr. Confirm this is intentional?"
}

What SSG does

SSG detects the redirect operator in the full command string. The block fires before the command runs, so error output is never suppressed. Claude Code receives the block and can reformulate without the redirect.

Ask the agent to log errors separately

stderr redirect was blocked. If you need to filter output, capture stderr separately:
  npm run build 2>build-errors.log
  if [ $? -ne 0 ]; then cat build-errors.log; fi
This keeps errors visible in the log file rather than discarding them.

Pair with structured logging

For long-running agent tasks, configure your build tools to write structured JSON logs that include error events — then pipe stdout to your log aggregator without suppressing stderr.

Monitor for error suppression patterns in CI

Some CI configurations use 2>&1 to merge streams for log aggregators that only capture stdout. Use ASK mode for CI environments where the redirect is intentional, and DENY for interactive agent sessions.

How your rule handles /dev/null variants

2>/dev/null silently discards all errors — the most dangerous form. 2>&1 merges streams, which is less harmful but still reduces debuggability. List both in your rule to catch both patterns.

Check the rule against your legacy scripts

Older shell scripts often use 2>&1 for compatibility reasons. Run echo '{"tool":"Bash","input":{"command":"npm run build 2>&1"}}' | ssg eval to check whether the rule fires before you commit to blocking it.

Filed by Claude Code
Engine ssg v1 · 2026-04-13
End of case file

Stop reading. Start governing.

Test a rule against any tool call right now. No install required.