[BUG] Desktop: send_message rejects a normal interactive session as "unattended (scheduled-task run or dispatched session)" — regression, worked 21 Aug, broken now
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?
Sending a cross-session message to a normal, long-lived, pinned, purely-interactive session now fails with:
Session <id> is unattended (a scheduled-task run or dispatched session); messages can't be delivered there.
This is the documented, correct behavior for genuinely unattended sessions (scheduled-task runs, remote-dispatched sessions). The problem is that the target session here is neither: it is a regular session created by hand on 29 May, pinned in the sidebar, opened and used interactively on and off for three months, with zero scheduled-task or remote-dispatch linkage in its own metadata (get_session returns no scheduled-task field, isRemote: false). No automation, cron, or dispatch is configured against this session.
Regression window, proven from the desktop app's own main.log
Worked on 21 Aug 2026: six separate send_message calls to this exact session ID all completed normally — LocalSessions.sendMessage → Sending message to session ... → Mapping internal session ... to CLI session ... → [Stop hook] Query completed → [CCD CycleHealth] healthy cycle (...s, hadFirstResponse=true). No rejection, no "unattended" mention anywhere in the log for that day.
Broken as of 31 Aug 2026, app 1.40609.0.0, runtime claude-code\2.1.247 (also present: 2.1.246): the identical call to the identical session ID now returns the "unattended" rejection immediately.
Localization
The word "unattended" does not appear anywhere in main.log, including at the exact moment of the failed calls. On 21 Aug, a successful send always logged LocalSessions.sendMessage: sessionId=... messageLength=... followed immediately by Sending message to session .... On the failed attempts today, neither of those lines is written at all. So the rejection is happening in a pre-send classification check added at the MCP/tool layer sometime after 21 Aug, before the call ever reaches LocalSessions.sendMessage — it is not coming from the underlying delivery mechanism, which is presumably unchanged (it worked identically to this same session on 21 Aug).
Independent second confirmation
A separate session, unrelated to the reproduction above, independently attempted to deliver its completed work to this same target session via the same channel and hit the identical rejection ("it's an unattended session and the channel refuses delivery"). It had to hand its report back to the user manually instead of via cross-session delivery. This rules out any one-off state on the sending side — two different sessions, two different attempts, same target, same rejection.
Impact
Any session that happens to trip whatever heuristic now flags it as "unattended" becomes permanently unreachable via cross-session messaging, silently and without any way for the user to see why, since the classification isn't based on any state visible through get_session.
What Should Happen?
A message sent to a normal, purely-interactive session with no scheduled-task or remote-dispatch linkage should be delivered normally, exactly as it was to this same session on 21 Aug 2026. The "unattended (scheduled-task run or dispatched session)" rejection should only fire for sessions that actually have that linkage.
Error Messages/Logs
Steps to Reproduce
- Have a long-lived, pinned, purely-interactive desktop session with no scheduled-task or remote-dispatch linkage (confirm via
get_session: no scheduled-task field,isRemote: false). - From another session, call the session-management
send_messagetool targeting it. - Observe the immediate rejection: "Session ... is unattended (a scheduled-task run or dispatched session); messages can't be delivered there."
- Confirm via the app's own
main.logthat the identical call to the identical session ID succeeded (fullsendMessage → Mapping internal session → Query completed → healthy cyclesequence, with no mention of "unattended" anywhere) on an earlier date before this regression — in this case, 21 Aug 2026, six times. - Note that the "unattended" string does not appear anywhere in
main.logeven at the moment of the failed calls, and theLocalSessions.sendMessage/ "Sending message to session" lines that always preceded a successful send are entirely absent on the failed attempts — the rejection fires before the call reaches that code path.
Reproduces consistently (multiple attempts, same session, same day) and was independently confirmed by a second, unrelated sending session hitting the identical rejection against the same target.
Claude Model
None
Is this a regression?
Yes, this worked in a previous version
Last Working Version
Working as of 21 Aug 2026 (desktop runtime present on that date; exact bundled version not captured at the time, but predates the 2.1.246/2.1.247 runtime present now)
Claude Code Version
Claude Code desktop app 1.40609.0.0, bundled runtime claude-code\2.1.247 (2.1.246 also present)
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
Other
Additional Information
Terminal/Shell = Other because this concerns the desktop app's own session-to-session messaging (the ccd_session_mgmt MCP tools), not a terminal session. Both the sender and the target session in this report run inside the Claude Code desktop app on Windows 11.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗