[BUG] Held-for-approval cross-session message to a background recipient has no approval UI — parked forever

Status Open
Reported on v2.1.226
Maintainer reply None cached
Activity 3 comments · opened Aug 11, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

Related: #85886 (same environment, discovered in the same collaboration session). Claude Code v2.1.226 (native install), macOS (Darwin 25.5.0); sessions managed via the claude agents dashboard.

When SendMessage targets another session, delivery is held for the recipient user's approval (the sender receives: "held for the recipient user's approval (recipient: uds:/tmp/cc-socks/<pid>.sock)"). For an interactive terminal recipient the approval prompt appears in that terminal. But when the recipient is a background session driven through the agents dashboard, the approval prompt is rendered nowhere the user can find:

  • not in the dashboard row / preview,
  • not when opening the session via Enter,
  • not in any notification surface we could locate.

The message is silently parked forever; the sender is told to wait for an approval that can never be granted. We hit this live: Session B successfully addressed Session A's socket and sent a reply; Session A never received it and its user never saw any approval prompt. A later message from B did get through while the user happened to have Session A's view focused — so the socket itself works; what's missing is the pending-approval surface for background sessions.

What Should Happen?

One of: (a) the agents dashboard surfaces pending cross-session message approvals for background sessions — e.g. as a "Needs input" row, which the dashboard already supports for other cases; or (b) messages to background recipients are queued and delivered on next activation, with the approval prompt shown at that point; or (c) the sender is told immediately that the recipient cannot approve, instead of an indefinite hold.

Error Messages/Logs

Steps to Reproduce

  1. Run two Claude Code sessions via the claude agents dashboard; both are daemon-hosted background sessions.
  2. From session X, ask Claude to SendMessage to session Y (Y has a live /tmp/cc-socks socket and appears in X's ListAgents).
  3. X's Claude receives the delivery notice: "held for the recipient user's approval (recipient: uds:/tmp/cc-socks/<pid>.sock)".
  4. Open session Y through the dashboard (Enter) and look for the approval prompt: dashboard row/preview, the opened conversation, any notification surface.
  5. Observe: no approval prompt is ever rendered anywhere; the message never arrives; the sender waits indefinitely.

Claude Model

Not sure / Multiple models

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.226

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

iTerm2

Additional Information

_No response_

View original on GitHub ↗

3 Comments

arthurmoraesfernandes-afk · 17 days ago

Decode in #86298 that may pinpoint the layer for this: the CLI settings schema defines crossSessionInbound: 'accept'|'hold'|'refuse' with a mode-parity default ("a sender that asserts no class is held while this session bypasses permission prompts"), and dialogExpiry (default 5m) resolves held messages to their "dropped-with-denial" outcome. The desktop bridge asserts no class in its origin:{kind:'peer'}, so every desktop-to-desktop message is gate-eligible; the CLI TUI contains a full approve/deny flow but desktop surfaces render no affordance. Your parked-forever card is the no-affordance hold on the dashboard surface.

github-actions[bot] · 6 days ago

We weren't able to reproduce this. Could you provide steps to trigger the issue — what you ran, what happened, and what you expected? This issue will be closed automatically if there's no activity within 7 days.

SuzieKJJ · 4 days ago

Re-tested on 2.1.246 — here is a minimal deterministic reproduction.

My original report framed this as "background/dashboard-driven sessions have no approval UI". That framing was too narrow and is probably why it did not reproduce. The actual trigger is a permission-mode mismatch, and the missing affordance is on the recipient side regardless of surface — including an interactive session with a live TTY.

Environment

  • Claude Code 2.1.246 (native install)
  • macOS 26.6.2 (Darwin 25.6.0, arm64)
  • Both sessions: crossSessionInbound unset (default)
  • Sender: defaultMode: "auto" in settings.json
  • Recipient: launched with --permission-mode bypassPermissions

Reproduction

  1. Session A (sender) in normal auto mode.
  2. Session B (recipient): mkdir -p ~/probe && cd ~/probe && claude --permission-mode bypassPermissions — an interactive terminal; its status line reads bypass permissions on (shift+tab to cycle).
  3. From A, SendMessage to B.
  4. A's tool result returns success: true with an ordinary delivery line — no mention of a hold.
  5. ~30s later A receives a separate notice: [Cross-session delivery notice] Your message to another session was held for the recipient user's approval (recipient: uds:/tmp/cc-socks/<pid>.sock). A's TUI also prints a yellow line: "Cross-session message held for approval … The recipient's session has different permission-mode settings, so their user must approve it before Claude sees it."
  6. B's terminal shows nothing — no prompt, no banner, no indicator anywhere.
  7. Typing into B (a full user turn, ~17s, completed normally) still surfaces no approval prompt. This rules out "the prompt renders on next activation", which was hypothesis (b) in my original report.
  8. ~9.5 minutes after the send, A received: [Cross-session delivery notice] Your message to another session was not approved before expiry (recipient: uds:/tmp/cc-socks/<pid>.sock). Not delivered to that session's Claude. So the sender is notified once the hold expires. Two caveats I would rather state than gloss over: the elapsed time is longer than dialogExpiry's documented 5m default (hold notice 16:04, expiry notice 16:13 local time), and I cannot rule out that the resolution happened on schedule and the notice was merely surfaced at my session's next turn boundary — at 16:10 I ran a tool call and no notice was pending at that point.

Control (same day, same machine)

The same SendMessage between two sessions with matching permission modes (both default, both background) was delivered immediately and never held. The recipient confirmed receipt via date, reported no approval prompt was shown to it, and its reply reached the sender directly. So the hold is specifically the mode-parity path, not cross-session messaging in general.

Why this is worse than my original report

  • The "their user must approve it" text is shown only to the party who cannot approve (the sender). The party who must act sees nothing at all.
  • The sender's tool result reports success before the hold is known, so an agent cannot tell at send time whether delivery actually happened.
  • The recipient's user is shown nothing at hold time, which is the moment that matters — the approval cannot be granted, so the message dies by default rather than by decision.

Re: @arthurmoraesfernandes-afk's decode

Corroborated against the 2.1.246 binary. Both settings exist, and dialogExpiry's own description reads: "Max time a permission/user dialog forwarded to a remote client stays parked awaiting an answer, and how long a HELD cross-session message awaits approval, before either resolves to its safe no-action default (cancelled / dropped-with-denial). Defaults to 5m to match the long-standing remote-dialog deadline; \"never\" disables the deadline."

The user-facing strings also include: "Your crossSessionInbound setting is \"hold\"; set it to \"accept\" to deliver held messages." So crossSessionInbound: "accept" on the recipient is a workaround for anyone hitting this today.

Suggested fix, unchanged in substance

Whichever surface the recipient is on, the approval has to be actionable there — or the sender must be told immediately that the recipient cannot approve, rather than being told only after the hold has already expired.