Discourage `| tail -N` / `| head -N` for long-running commands; prefer run_in_background and progressive Read

Resolved 💬 3 comments Opened May 1, 2026 by onhate Closed May 5, 2026

Summary

When Claude Code runs a long-running command (e.g. pulumi preview, npm run build, terraform plan, a test suite), it frequently pipes output through tail -N or head -N to keep the result short. For long, progress-emitting commands this is actively harmful in two ways: it discards earlier lines that often contain the failure, and the user can never see the live progress while the command runs.

I'd like the prompt / system guidance to explicitly steer the model toward using the existing run_in_background: true mechanism (which already captures full stdout/stderr to an .output file) and reading from that file with offset/limit windows, instead of pre-truncating with tail / head.

Why this matters

  1. Truncation hides root causes. The most useful output of a long-running command is rarely at the tail — for builds, type checkers, and infra previews, the first error is usually the one to fix; later lines are downstream noise. | tail -200 discards exactly the line you need.
  1. Pipes buffer. cmd | tail -N does not stream — tail waits for EOF before printing anything. So a 10-minute command produces zero output until it exits. The user has no idea whether it's progressing, hung, or about to fail. I hit this in a real session with pulumi preview --diff | tail -200: the log file was empty for the entire run.
  1. The user is left blind. Even if the model is content with a truncated tail, the human in the loop usually wants to follow progress live (tail -f the .output file, watch the diff scroll, spot the suspicious line early). Pre-piping through tail strips that affordance.
  1. The background mechanism already solves this cleanly. run_in_background: true writes the full output to an .output file. The model can Read that file with offset/limit to inspect any section without dumping it all into context, and can re-read as the file grows. The user can tail -f it directly. At completion, the model has access to the full log to summarize. No information is lost; context isn't bloated.

Proposed guidance change

Add a rule to the Bash-tool guidance roughly like:

For commands expected to run longer than ~30 seconds or that emit progressive output (builds, test suites, infra previews, deployments), prefer run_in_background: true over piping through tail -N / head -N. The background mode preserves full output for both the user and later model inspection; a tail/head pipe discards information and prevents progress monitoring. Use Read with offset/limit on the resulting .output file to inspect specific regions without bloating context.

Edge cases worth allowing

  • Short, deterministic commands where the last line is genuinely the answer (e.g. git rev-parse HEAD | tail -1) are fine.
  • head -N for inspecting the start of a known-large file (e.g. peeking at a CSV header) is fine.
  • The rule is specifically about wrapping a long-running command's live output stream through a truncating pipe.

Tradeoffs

  • Background mode adds one extra Read step before the model can comment on the result. Modest cost; saves much more in re-runs when truncation hides the failing line.
  • Some commands buffer their own stdout when not connected to a TTY, which limits live monitoring even with the background approach. That's a separate problem and isn't made worse by this change.

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗