Skip to content

Claude Code notifications silently fail: hook subprocesses have no controlling TTY, /dev/tty write returns ENXIO #54

@jakefoster

Description

@jakefoster

Summary

warp-notify.sh (both v2.0.0 and legacy/) emits OSC 777 by writing to /dev/tty. In current Claude Code builds, hook subprocesses are spawned without a controlling terminal, so the write fails with Device not configured (ENXIO) and notifications are silently dropped.

Diagnostic

I instrumented a Stop hook in ~/.claude/settings.json to probe the hook execution environment:

tty=not a tty
devtty_exists=yes
devtty_writable=yes (test -w only checks file perms, not openability)
WARP_CLIENT_VERSION=v0.2026.05.18.05.32.stable_02
WARP_CLI_AGENT_PROTOCOL_VERSION=1
plain_osc_exit=1 stderr=/dev/tty: Device not configured
structured_osc_exit=1 stderr=/dev/tty: Device not configured

  • should_use_structured() returns true (env vars present, build is past the broken-release threshold) — the gate is not at fault.
  • Both the legacy notify;<title>;<body> and the v2.0.0 warp://cli-agent JSON formats fail at the same > /dev/tty redirect.
  • macOS Notifications permission for Warp is enabled.

Repro

  1. Add a Stop hook to ~/.claude/settings.json that just runs printf '\033]777;notify;test;hi\007' > /dev/tty.
  2. End any Claude Code turn.
  3. No banner; if you redirect stderr to a file, you'll see Device not configured.

Suggested direction

Hook subprocesses can't reach the user's terminal directly. Options to consider:

  • Write to stdout instead of /dev/tty. Whether Warp would render OSC from a captured stream depends on how Claude Code forwards hook stdout — needs investigation.
  • Detect ENXIO and fall back to a transport that doesn't require a TTY (e.g., osascript on macOS, an OS-level toast on Linux/Windows).
  • Coordinate with Anthropic on a documented "notification channel" hook output schema so plugins don't have to side-channel through /dev/tty.

Environment

  • macOS: Darwin 25.4.0
  • Warp: v0.2026.05.18.05.32.stable_02 (stable)
  • Plugin: warp@claude-code-warp v2.0.0
  • Claude Code: Opus 4.7 (1M context) CLI

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions