A troubleshooting guide
Claude Code notifications not working? Start here.
On a Mac, Claude Code’s own alert is passed through your terminal, so whether you see it depends on the terminal, on tmux, and on one macOS switch. Here is each cause, in the order it’s usually the answer, with the fix from Claude Code’s docs.
Your terminal decides first
By default Claude Code sends a desktop notification in only three terminals. Everywhere else it stays quiet until you choose a different way to be told.
| Terminal | Shows the notification | What to do |
|---|---|---|
| Ghostty | Shows the notification: Yes, with no setup | If nothing appears, Ghostty itself isn't allowed to notify: see the first reason below. |
| Kitty | Shows the notification: Yes, with no setup | As for Ghostty: check Kitty's notification permission in System Settings. |
| iTerm2 | Shows the notification: Yes, once forwarding is on | Settings → Profiles → Terminal: check “Notification Center Alerts”, then Filter Alerts → “Send escape sequence-generated alerts”. |
| Warp, Terminal.app, VS Code’s terminal and the rest | Shows the notification: No | This is Claude Code’s own notification; some of these, Warp among them, have agent alerts of their own. Ring the terminal bell instead with preferredNotifChannel, or add a Notification hook. Both are below. |
| Any of these, inside tmux | Shows the notification: Not until passthrough is on | tmux swallows the notification unless allow-passthrough is on. One line in ~/.tmux.conf. |
Six reasons it stays silent
1
Your terminal isn't allowed to notify
The alert is posted by your terminal app, so macOS needs to let that app notify. Open System Settings → Notifications, find your terminal and turn on Allow Notifications. A Focus mode or Do Not Disturb holds alerts back too. It’s the first thing Claude Code’s docs say to check.
2
You were looking at it
Claude Code only notifies when you appear to be away from the terminal. A permission prompt waits until you haven’t typed for about six seconds; “waiting for you” comes about 60 seconds after Claude finishes, if you haven’t typed since. To test it, start something, switch to another app and wait.
3
tmux is swallowing it
Inside tmux the notification never reaches the terminal around it unless passthrough is allowed. Add the line below, run tmux source-file ~/.tmux.conf, and it applies to the running server.
4
iTerm2 isn't forwarding it
iTerm2 receives the notification but keeps it to itself until you turn on Notification Center Alerts and, under Filter Alerts, escape sequence-generated alerts. Both are in the profile's Terminal settings.
5
Your osascript hook fails silently
A hook that runs osascript -e 'display notification …' posts as Script Editor. If Script Editor has never been allowed to notify, the command fails without a word and macOS never asks. Run the test command below once, then allow Script Editor in System Settings → Notifications.
6
Your “finished” hook fires on every reply
A hook on Stop runs whenever Claude finishes responding, not only when the task is done. It doesn’t run when you interrupt, and an API error runs StopFailure instead. For “Claude is waiting on me”, use the Notification event with the permission_prompt or idle_prompt matcher.
The settings, ready to paste
Ring the terminal bell, for terminals without the notification
~/.claude/settings.json
{
"preferredNotifChannel": "terminal_bell"
}For Warp, Terminal.app, VS Code's terminal and anything else that doesn't show Claude Code's desktop notification.
Let notifications out of tmux
~/.tmux.conf
set -g allow-passthrough onThen run tmux source-file ~/.tmux.conf to apply it to the running server.
A desktop notification of your own, when Claude asks permission
~/.claude/settings.json
{
"hooks": {
"Notification": [
{
"matcher": "permission_prompt",
"hooks": [
{
"type": "command",
"command": "osascript -e 'display notification \"Claude Code needs your attention\" with title \"Claude Code\"'"
}
]
}
]
}
}Runs alongside the built-in notification. Drop the matcher to hear about every notification type.
Make Script Editor appear in Notifications
Terminal
osascript -e 'display notification "test"'Nothing shows the first time. Allow Script Editor in System Settings → Notifications, then run it again.
Or skip the per-terminal setup
An alert that doesn’t go through the terminal
Perch takes a different route. Its hooks report each Claude Code session to the Perch app on your Mac, which posts the alert itself — so the terminal you use, tmux passthrough, iTerm2’s filters and Script Editor’s permission don’t come into it. The one switch that matters is Perch’s own, in System Settings → Notifications.
You hear about a permission prompt the moment it’s drawn, the menu bar says which session is waiting, and clicking the alert lands in the exact pane it came from. The same alert reaches your iPhone and Apple Watch with Allow and Deny on it, and an error is never announced as a finish. Every alert Perch sends.
Questions