[BUG] Dispatch cannot start a second Code session in the same folder since 1.44121.x: exclusiveCwd hardcoded true in startCodeSession

Status Fixed / completed
Maintainer reply None cached
Activity 6 comments · opened Sep 3, 2026 · closed Sep 4, 2026

Summary

Since Claude Desktop 1.44121.x (Windows, MSIX), Dispatch can no longer start a second Code session in the same folder. The call fails with:

Failed to start code session: Another Claude Code session is already active in this directory.

This is a regression: the flag that triggers the check does not exist in any build up to and including 1.37937.3.0. It also contradicts the documented behaviour — Desktop application → Work in parallel with sessions states that multiple sessions can run in parallel and that Dispatch can start sessions for you.

Sessions started by hand in the app are unaffected. Only the Dispatch path is blocked.

Environment

  • Windows 11 Pro, 26200
  • Claude Desktop 1.44121.4.0 (MSIX, installed from claude.com)
  • Working folder is not a git repository (so no worktree isolation is possible)

Steps to reproduce

  1. Have a folder that is not a git repo, with at least one non-archived Code session already in it.
  2. From Dispatch, ask to open a new Code session in that same folder.
  3. The call fails with the error above. Every further attempt fails until the existing session is archived.

Expected: a second parallel Code session in that folder, as documented.
Actual: CwdInUseError.

Root cause (from app/resources/app.asar)

The check is gated behind an exclusiveCwd option:

if (n?.exclusiveCwd) {
    let t = this.findActiveSessionByCwd(f, r);
    if (t) throw new Hu(e.cwd, ...)   // CwdInUseError
}

exclusiveCwd appears exactly twice in the whole bundle: once where it is read (above), and once where it is set — hardcoded true in the Dispatch bridge:

startCodeSession: async (cwd, message, title, model) => {
  ...
  return o.startSession(
    {cwd, message, title, model, permissionMode},
    {dispatchParentId, dispatchParentOrigin:"local",
     origin:{kind:"auto-continuation"}, initiator:"dispatch",
     exclusiveCwd:!0}
  )
}

No other session-start path sets it, which matches the observed behaviour (manual sessions still work).

What counts as "in use" is any non-archived session with a matching cwd or originCwd:

for (let n of this.sessions.values())
  if (!(n.isArchived || n.sessionId === t) && (
        normalizeCwdKey(n.originCwd || n.cwd) === e ||
        (n.originCwd && n.originCwd !== n.cwd && normalizeCwdKey(n.cwd) === e)
     )) return n.sessionId

Because originCwd is compared too, a git worktree session would also match on its base repo path — so worktree isolation does not appear to exempt this path either.

When it appeared

grep for exclusiveCwd / CwdInUseError across the app.asar of every build still present on this machine:

| Build | Date | exclusiveCwd | CwdInUseError |
|---|---|---|---|
| 1.32885.1.0 | Aug 19 | 0 | 0 |
| 1.34493.0.0 | Aug 21 | 0 | 0 |
| 1.37937.0.0 | Aug 26 | 0 | 0 |
| 1.37937.1.0 | Aug 26 | 0 | 0 |
| 1.37937.3.0 | Aug 27 | 0 | 0 |
| 1.44121.4.0 | Sep 3 | 2 | 2 |

Deployment log on this machine: 1.40609.1.0 → 1.44121.2.0 (05:48) → 1.44121.4.0 (07:09), both on Sep 3. Dispatch could open parallel sessions in this folder the day before, on 1.40609.1.0.

Impact

For a non-git working folder this removes the only remote entry point into it:

  • opening a Code session from the phone goes through a GitHub repo, so a non-git folder is not reachable that way;
  • Dispatch was the remaining route, and it is now blocked;
  • only a manual session at the keyboard still works.

Archiving is not a workable mitigation: it clears the folder only until the next session exists, and it cannot give two live parallel sessions at all, since the first one immediately blocks the second.

Suggested fix

Either drop exclusiveCwd:!0 from startCodeSession, or make it configurable, or scope the check to sessions that are actually running rather than to every non-archived session in the folder.

Note

The 1.44121.1 fix "sessions failing to start on Windows for accounts with many saved artifacts, scheduled tasks, or connected folders" was reverted in 1.44121.2 and is not restored in 1.44121.4, so that failure mode is also live again. That may be a separate issue, but it lands on the same users.

---
Investigated with Claude Code.

View original on GitHub ↗

3 Comments

serge-zol · 1 month ago

Follow-up with application-side logs, which I could not produce in the original report.

Correction to myself first: I initially concluded the app writes no logs since Aug 23. That was wrong — the log directory moved. It is no longer %APPDATA%\Claude\logs but %LOCALAPPDATA%\Claude\Logs, and the move happened during the 1.32352.1.0 → 1.34493.1.0 update. The seam is visible to the second:

old  …\Roaming\Claude\logs\main.log   last lines
  2026-08-23 19:58:04 [info] beforeQuitForUpdate handler fired, going down for update
  2026-08-23 19:58:05 [info] Windows session ending (close-app) - quitting the app

new  …\Local\Claude\Logs\main1.log    first line
  2026-08-23 19:58:10 [info] Starting app { appVersion: '1.34493.1', isPackaged: true }

Logs are continuous since then. So issue #91640 ("app writes no logs") is not what I was seeing.

The failures, as the app records them

Seven refusals today, all on the Dispatch path:

09:38:48 [error] [DispatchTools] start_code_task failed for D:\…\sb-projects:
         Another Claude Code session is already active in this directory
09:52:02 [error] same, sb-projects
10:14:43 [error] same, sb-projects
13:25:46 [error] [DispatchTools] start_code_task failed for D:\…\sb-projects\sb-crm:
         A Claude Code session (local_1bfd54f6-…) is already active in this directory
13:29:28 [error] same, sb-crm
13:34:51 [error] same, sb-crm
14:26:43 [error] [DispatchTools] start_code_task failed for D:\…\sb-projects\casper-sbs:
         A Claude Code session (local_7f9ad395-…) is already active in this directory

Every entry is tagged [DispatchTools] start_code_task — matching the code path where exclusiveCwd:!0 is hardcoded. Sessions opened by hand in the Code tab were never refused.

Note the last one: casper-sbs is a git repository, and it was refused just like the non-git folder. So worktree isolation does not exempt this path, which is consistent with the check comparing originCwd as well as cwd.

First refusal came at 09:38 — about 2.5 hours after the update landed.

Update timeline from the app's own log

[updater] Update URL: https://api.anthropic.com
[updater] MSIX detected: windowsStore=true, appPathMatch=true, source=windowsStore

05:47:10  Checking for updates
05:47:11  Found an update, downloading
05:48:03  Update downloaded and ready to install { releaseName: 'Claude 1.44121.2' }
05:58:03  Staged version 1.44121.2 is still current
05:58:38  Version changed since last launch: 1.40609.1 → 1.44121.2

06:58:38  Using GrowthBook check_interval_ticks=1 (default 4)
06:58:39  Found an update, downloading
06:59:13  Update downloaded and ready to install { releaseName: 'Claude 1.44121.4' }
07:09:13  Staged version 1.44121.4 is still current
07:09:47  Version changed since last launch: 1.44121.2 → 1.44121.4

Two observations, secondary to this issue but worth recording:

  • The gap between "downloaded and ready" and applying the update is exactly 10 minutes both times (05:48:03 → 05:58:03, 06:59:13 → 07:09:13), and the apply path forces the app to close: the deployment log shows RegisterByPackageFamilyName … ForceApplicationShutdownOption after Windows had twice refused with Packages were not updated because affected apps are still running. So two builds landed under an active user session within 80 minutes.
  • check_interval_ticks=1 (default 4) — a remote flag shortened the update check interval right before the second update.

So the version that introduced the behaviour reached this machine through two forced restarts in one morning, and the first user-visible symptom appeared 2.5 hours later.

serge-zol · 1 month ago

Follow-up with a concrete repro of the failure mode: the directory is held by a stale session record, not by a live session.

Environment: Claude Desktop 1.44121.4.0 (MSIX), Windows 11, CLI 2.1.258.

What happened

  • Dispatch (start_code_task) refused every attempt to open a session in D:\...\sb-projects with Another Claude Code session is already active in this directory.
  • No session was running there. The app had been restarted. The block survived the restart.
  • Scanning the session store — %LOCALAPPDATA%\Packages\Claude_*\LocalCache\Roaming\Claude\claude-code-sessions\<installId>\<accountId>\local_<uuid>.json — showed exactly one record with isArchived: false and that cwd, last active two days earlier. Its CLI process was long gone.
  • Deleting that one session in the UI freed the directory immediately (134 -> 133 records), and Dispatch could start a session there again.

Why this is worth fixing

  1. findActiveSessionByCwd() treats "not archived" as "active". Liveness is actually known to the app: live CLI sessions are registered in ~/.claude/sessions/<pid>.json, and the session object carries query. A dead-but-unarchived record blocks the directory forever, across restarts.
  2. exclusiveCwd is hardcoded true on the Dispatch start path only. Manual starts have no such check — and two sessions started manually in the same directory run happily side by side (measured: two live PIDs, same cwd). So the restriction is policy, not a technical constraint.
  3. The Dispatch tool set (session_info, list_sessions, read_transcript, start_task, start_code_task, send_message, set_agent_name, list_code_workspaces, list_projects) has no archive or delete tool. archive_session lives in ccd_session_mgmt, available to code sessions only. So from a phone — where Dispatch is the only channel to the machine — the state is unrecoverable: the tool that could clear it can only run in a session that cannot be started because of it.
  4. The error text names neither the offending session nor any way out. When the record is not visible to the caller, even the session id is omitted.

Suggested fixes, in order of value

  • Occupancy should be based on a live session, not on isArchived.
  • Give Dispatch an archive/release tool, or auto-release records whose process is gone.
  • Make the message actionable: name the holding session and how to release it.

Request: please allow Dispatch to open several sessions in one folder

Beyond the stale-record bug, the one-session-per-directory policy itself breaks my main workflow, and I would really like it reconsidered — or at least made configurable.

I work from my phone most of the time. Dispatch is my only channel to the machine. I do not remember the full structure of my local repo, so I cannot reliably name the exact target subfolder when asking Dispatch to start a session. What works for me is the obvious thing: Dispatch opens a session at the repo root, and then, inside the session, we navigate to whatever subfolder the task actually concerns.

That means several concurrent sessions at the same root — which is exactly what the current policy forbids. The suggested workaround (use different subfolders) does not help: naming the subfolder up front is the very thing I cannot do from a phone, and it also costs auto-memory and local-scope MCP, both of which are bound to the path.

Concretely, any of these would solve it for me:

  • lift the restriction for Dispatch-started sessions (manual starts already allow it, and they work fine side by side), or
  • make it a setting, or
  • prompt instead of refusing ("a session is already open here — open another one?").

Thanks for looking at this.

ProfessorSagacious · 1 month ago

Same regression on macOS, same day, independently traced to the same check.

Environment: macOS 25.5.0, Claude.app 1.44121.4 (Electron 42.10.0), Claude Code desktop SDK 2.1.258. App bundle replaced 2026-09-03 01:51 local. Previous SDK 2.1.255 did not have this behavior.

Evidence it is a regression: on 2026-09-01 (pre-update) three Dispatch-spawned Code sessions in the same non-git folder ran concurrently for over an hour (main.log: [DispatchTools] Spawned host code session … at <folder> at 08:23, 12:40, 13:11, with lifespans overlapping until 14:31). After the update, every Dispatch spawn into that folder fails:

[error] [DispatchTools] start_code_task failed for <folder>: Another Claude Code session is already active in this directory.

(12:15, 13:24, 13:50, 15:20 local.) Manual sessions from the Code tab in the same folder were never refused; three ran side by side while Dispatch was being refused.

Confirming the "stale record" finding: the check is findActiveSessionByCwd, which walks every loaded session record and returns the first non-archived one whose cwd matches. It does not consult isRunning or ~/.claude/sessions/<pid>.json. In my case the folder held 791 un-archived scheduled-task run sessions back to July 1 (these are hidden from Recents, #78229, and never auto-archived, #90251), so the user could see only 4 sessions and had no way to find or archive the blockers. After archiving those 791 on disk with the app quit, the spawn still failed on the 4 remaining idle chat sessions, so idle chats block too. A control spawn into a folder with zero session records succeeded immediately.

Net: with the current check, Dispatch cannot target any folder the user has ever had a conversation in unless every session there is archived, and folders hosting scheduled tasks re-block on the next run. +1 to scoping the check to live sessions (the pid registry already exists) or dropping exclusiveCwd from the Dispatch path.

Showing cached comments. Read the full discussion on GitHub ↗