Skip to content

fix: silence /dev/tty redirect errors when no tty is attached - #83

Open
kevmi wants to merge 1 commit into
warpdotdev:mainfrom
kevmi:fix/tty-redirect-order
Open

fix: silence /dev/tty redirect errors when no tty is attached#83
kevmi wants to merge 1 commit into
warpdotdev:mainfrom
kevmi:fix/tty-redirect-order

Conversation

@kevmi

@kevmi kevmi commented Aug 31, 2026

Copy link
Copy Markdown

Problem

On Windows / Git Bash the Stop hook runs without a controlling terminal, so every turn prints:

/c/Users/<user>/.claude/plugins/cache/claude-code-warp/warp/2.2.0/scripts/emit-terminal-sequence.sh: line 82: /dev/tty: No such device or address

The 2>/dev/null was meant to suppress this, but shell redirections are applied left to right. In > /dev/tty 2>/dev/null, the shell opens /dev/tty while stderr is still the inherited one, so the failed-open message escapes before 2>/dev/null takes effect.

Fix

Swap the order to 2>/dev/null > /dev/tty so stderr is muted before the open is attempted.

$ ( printf 'x' > /dev/tty 2>/dev/null ) ; echo "exit=$?"
bash: line 1: /dev/tty: No such device or address
exit=1

$ ( printf 'x' 2>/dev/null > /dev/tty ) ; echo "exit=$?"
exit=1

Exit status is unchanged, so the if in emit_terminal_sequence still falls through to the JSON path correctly.

Verification

All three branches of emit_terminal_sequence exercised with no tty attached:

CLAUDE_CODE_VERSION Output stderr
unset (unknown) {"terminalSequence":"HELLO"} clean
2.5.0 (new) {"terminalSequence":"HELLO"} clean
2.0.0 (old, tty path) none, exit 0 clean

bash -n passes on both files. Same one-line change applied to legacy/warp-notify.sh, which has the identical pattern.

🤖 Generated with Claude Code

https://claude.ai/code/session_01PWTCPGfRHRHJxiuXUjxP6X

Redirections are applied left to right, so `> /dev/tty 2>/dev/null`
opens /dev/tty while stderr is still the inherited one. When /dev/tty
is unavailable the shell's "No such device or address" message escapes
to stderr before 2>/dev/null takes effect.

Swapping the order to `2>/dev/null > /dev/tty` mutes stderr first, so
the failed open is silent. Exit status and the JSON fallback path are
unchanged.

This surfaces on Windows/Git Bash, where the Stop hook has no
controlling terminal and every turn prints:

  emit-terminal-sequence.sh: line 82: /dev/tty: No such device or address

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PWTCPGfRHRHJxiuXUjxP6X

@warp-factories warp-factories Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Overview

Correctly fixes the redirection-order bug: swapping to 2>/dev/null > /dev/tty mutes stderr before the /dev/tty open is attempted, so the "No such device or address" message no longer escapes when no controlling terminal is attached, with exit status unchanged (verified below). No blocking issues found.

Concerns

  • Neither changed script has a regression test. plugins/warp/tests/test-hooks.sh exercises emit_terminal_sequence but never asserts stderr is empty when /dev/tty open fails, so this exact bug (and any regression of it) would not be caught by CI. A test that runs the "unknown version" fallback (or the old-version branch) with stderr captured and asserts it's empty would cover this.

Verdict

Checks: build n/a (shell scripts), tests pass (existing suite unaffected by this change), CI not yet run (fork PR pending workflow approval), visual proof n/a

Found: 0 critical, 1 important, 0 suggestions, 0 nits

Reproduced the claimed behavior in a detached (no controlling terminal) shell: old ordering leaks bash: line 1: /dev/tty: No such device or address to stderr with exit 1; new ordering produces empty stderr with the same exit 1.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant