needs-you

Guides

Troubleshooting

Work from the sender toward the Mac: can the sender reach a hub, did the hub store the item, can the Mac see it, is the Mac showing the right context.

Reporting a problem: what to include, and how to save the app's log with tokens and invite codes masked, is in Testers → Report a problem.

Start here: needs-you doctor #

On the sender, run:

needs-you doctor          # or ~/.local/bin/needs-you doctor if it isn't on PATH
needs-you doctor --json   # the same, for agents: {ok, version, checks: [{check, status, detail, hint}]}

It checks the env file (and that its mode is 600), whether needs-you and ~/.local/bin are on PATH, each hub URL (reachable, hub version, the token's name and role), the outbox (queued, failed, oldest), each agent's hooks or plugin (Claude Code, Codex, Gemini, opencode, Copilot, Kimi, Grok, Cursor, Cline, Aider), the Claude skill, the MCP server and agent instructions if you installed them, Orca settings, updates, and the 5-minute flush schedule. Each line is OK, WARN, FAIL or INFO. Every WARN and FAIL has one next step under it (after ->): a command to run as is, or exactly what to ask for, such as a new invite link (<invite link> is the only placeholder). It exits 1 if any check is FAIL. It's read-only: it never posts an item, never flushes the outbox and never prints the token (only "set" and its length).

Quick checks by hand #

# on the sender
. ~/.config/needs-you/env
for u in $(echo "$NEEDS_YOU_URLS" | tr ',' ' '); do
  printf '%s  ' "$u"; curl -sS -o /dev/null -w '%{http_code}\n' --max-time 5 "$u/v1/health"
done
ls ~/.local/state/needs-you/outbox/ 2>/dev/null   # queued items that haven't reached a hub
tailscale status | head                          # is this machine on the tailnet?
# macOS with the Tailscale app: /Applications/Tailscale.app/Contents/MacOS/Tailscale status

A sender can't reach the hub #

Setting up Tailscale, or checking it step by step: Tailscale.

SymptomLikely causeFix
curl: (6) Could not resolve hostMagicDNS off, or the machine isn't on the tailnettailscale up; enable MagicDNS in the admin console; tailscale status should list the hub
curl: (7) Failed to connect / timeoutHub down, or listening on a different address/portOn the hub: systemctl status needs-you-hub, journalctl -u needs-you-hub -n 50 (see Server hubs for the unit name)
Times out only from some machinesTailscale ACLAllow those machines (or their tag) to reach the hub's tag on tcp:8765
Works by IP, not by nameDNSUse the full MagicDNS name, <hub>.<tailnet>.ts.net
HTTP 421 "doesn't answer to that host name"The URL uses a name the hub doesn't know as its own (a custom DNS name or alias); this is its DNS-rebinding protectionUse the hub's public URL (MagicDNS name) or tailnet IP, or add the name to the hub's allowed_hosts (--allowed-host, or NEEDS_YOU_HUB_ALLOWED_HOSTS for the Mac app's hub, Server hubs)
HTTP 401 / 403Wrong, revoked, or Mac-only tokenGet a new invite link and re-run its installer with --force
Times out only while the Mac sleepsThe Mac's own hub is asleepExpected: items queue and the 5-minute flush sends them after it wakes. Add a server hub to avoid the wait.
Times out from servers, works on the MacTailscale is down on the Mac (the app's hub then listens only on 127.0.0.1), or the macOS firewall blocks itBring Tailscale up on the Mac; the hub picks up the tailnet address by itself (Settings… → Your inbox shows the URL). Allow python3 in System Settings → Network → Firewall
HTTP 400Validation: title > 100 chars, body > 2,000, > 6 links, a link scheme not on the allow-list, a bad context/kind/priorityFix the item; the response body says which field
HTTP 429 or "too many open items"The sender has 60 open items: something is loopingStop the loop; resolve the stale keys

The CLI never fails your job because of the hub. It queues to ~/.local/state/needs-you/outbox/ and sends on the next call or needs-you flush (the invite installer schedules one every 5 minutes). Items sitting in the outbox mean no hub has accepted them yet. The outbox keeps at most 500 requests and 7 days; older ones are dropped with a warning.

SymptomCauseFix
This invite link is unknown, expired or revoked (exit 1)What it saysMake a new link
invite ... has no uses left (exit 1)A new machine, or --force, on a used-up linkMake a new link, or one with more uses
HTTP 429 / "too many failed invite attempts"10 failed tries from this IP in 10 minutesWait 10 minutes; check the link was pasted whole
"This invite (..., role owner) is for the Mac app"An owner/reader link was used on a serverOpen the needsyou:// link on the Mac; make a sender link for servers
Re-running the one-liner (or --uninstall) fails after the link expiredRe-runs work until expiry, not afterUpdate with needs-you update; remove by hand (Add a sender); or make a new link
curl: (22) ... 404 and no other outputA hub older than this release (it 404s dead links, and bash runs the empty script)Make a new link; update the hub
"kept the existing token"The machine was already set upExpected. --force redeems again and replaces the token
Installer says no hub answeredThe hub is asleep or unreachable right nowThe setup still completed; the test item is queued
Not set up: Gemini CLI hooks ... (or Codex, Claude Code, opencode, the skill) at the end; exit 3 if nothing you asked for was set upThat agent's config couldn't be changed (unreadable JSON such as comments in settings.json, a symlink, a failed download); the message above it says whichFix the file it names, then re-run the one-liner with the flag the line gives. The CLI and token are already set up

setup-sender.sh (manual setup) #

Items post, but nothing shows on the Mac #

  1. Context and hours: a work item at 21:00 shows only as the faint second number (0 · 1). Use the toggle in the expanded header, or check the work-hours setting.
  2. Kind: done and info items never raise the count. They're in the collapsed Recent section.
  3. Snoozed: press Control-Option-Space (⌃⌥Space, or your configured shortcut) to bring the panel back.
  4. Mac can't reach a server hub: the Mac needs Tailscale up. Hover the idle pill: the "last check" time should be recent.
  5. Wrong hub: the sender's NEEDS_YOU_URLS must include the Mac's hub or a server hub peered with it.
  6. Hubs out of sync: if the Mac polls hub-a and the sender wrote to hub-b, replication should copy it within seconds. If it doesn't, check the peer list and the replication outbox on hub-b (Server hubs).

Duplicate or stale cards #

Claude Code hooks #

Setup per environment (SSH, tmux, VS Code Remote-SSH, Orca): Claude Code everywhere. Turn on the debug log and simulate an event:

echo '{"session_id":"t1","cwd":"'"$PWD"'","notification_type":"idle_prompt","message":"test"}' |
  NEEDS_YOU_AGENT_ALERTS=1 NEEDS_YOU_HOOK_LOG=/dev/stderr ~/.claude/hooks/needs-you-hook.sh notify
Log saysMeaning
nothing at allNot opted in. Set NEEDS_YOU_AGENT_ALERTS=1, or run inside Orca. Check it isn't 0 in ~/.config/needs-you/env.
needs-you CLI not foundInstall it (an invite link, or setup-sender.sh --install-cli) or set NEEDS_YOU_BIN.
notify agent:... -> 0Posted (or queued). Check the hub and the Mac as above.
notify agent:... -> 1The CLI failed. Run the same needs-you add by hand to see the error.

Other checks:

Codex hooks #

needs-you doctor has a codex hooks line. Simulate an approval prompt and its resolve with a log to stderr:

echo '{"hook_event_name":"PermissionRequest","session_id":"t1","cwd":"'"$PWD"'","tool_name":"Bash","tool_input":{"command":"make test"}}' |
  NEEDS_YOU_AGENT_ALERTS=1 NEEDS_YOU_HOOK_LOG=/dev/stderr ~/.codex/hooks/needs-you-hook.sh notify codex
echo '{"session_id":"t1"}' | NEEDS_YOU_AGENT_ALERTS=1 NEEDS_YOU_HOOK_LOG=/dev/stderr ~/.codex/hooks/needs-you-hook.sh resolve codex

The log lines mean the same as for the Claude Code hooks above. Codex-specific causes:

Copilot CLI hooks #

needs-you doctor has a copilot hooks line. In copilot mode the hook finishes in the background, so log to a file:

echo '{"sessionId":"t1","cwd":"'"$PWD"'","notification_type":"permission_prompt","message":"Run command: make test"}' |
  NEEDS_YOU_AGENT_ALERTS=1 NEEDS_YOU_HOOK_LOG=/tmp/ny-hook.log ~/.copilot/hooks/needs-you-hook.sh notify copilot
sleep 2; cat /tmp/ny-hook.log

Copilot-specific causes:

Kimi Code hooks #

needs-you doctor has a kimi hooks line, and kimi doctor checks that Kimi accepts config.toml. In kimi mode the hook finishes in the background, so log to a file:

echo '{"hook_event_name":"PermissionRequest","session_id":"session_t1","cwd":"'"$PWD"'","tool_name":"Bash","display":{"command":"make test"}}' |
  NEEDS_YOU_AGENT_ALERTS=1 NEEDS_YOU_HOOK_LOG=/tmp/ny-hook.log ~/.kimi-code/hooks/needs-you-hook.sh notify kimi
sleep 2; cat /tmp/ny-hook.log

Kimi-specific causes:

Grok Build hooks #

needs-you doctor has a grok hooks line, and grok inspect lists the hooks Grok loaded. In grok mode the hook finishes in the background, so log to a file:

echo '{"hook_event_name":"Notification","notificationType":"permission_prompt","session_id":"t1","cwd":"'"$PWD"'"}' |
  NEEDS_YOU_AGENT_ALERTS=1 NEEDS_YOU_HOOK_LOG=/tmp/ny-hook.log ~/.grok/hooks/needs-you-hook.sh notify grok
sleep 2; cat /tmp/ny-hook.log

Grok-specific causes:

Cursor, Cline and Aider #

needs-you doctor has cursor hooks, cline hooks and aider notifications lines. None of the three has an approval hook, so no card when the agent asks to run something: that's expected, not a fault. The hook finishes in the background in all three, so log to a file (NEEDS_YOU_HOOK_LOG=/tmp/ny-hook.log on the test commands in Cursor, Cline or Aider).

GitHub poller #

Orca automations #

This page is docs/guides/troubleshooting.md in the repo. View or edit it on GitHub.