claude-code - 💡(How to fix) Fix [BUG] Claude in Chrome `file_upload` rejects all scheduled-task sessions with misleading error (real cause: INVALID_SESSION)

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Error Message

mcp__Claude_in_Chrome__file_upload rejects every file path when called from a Claude Code Desktop scheduled task, with a misleading error message: (b) the error should surface the real INVALID_SESSION reason instead of masking it as "only files the user has shared". The current message sent me down hours of dead-end debugging trying to "share" the file in every conceivable way (which is impossible for CCD sessions — the validator throws before the allowlist is even checked).

Error Messages/Logs

2026-05-28 11:33:20 [warn] uploadLocalFile: unknown local agent mode session local_2baaad08-b19c-4a36-8565-fbf84e649d70 2026-05-28 11:33:20 [warn] [chromeFileUpload] rejected path for session local_2baaad08-b19c-4a36-8565-fbf84e649d70: /Users/mmhw/Downloads/MO/Standard Audio - Heidi.m4a ([INVALID_SESSION] Unknown session: local_2baaad08-b19c-4a36-8565-fbf84e649d70) The [CCD start-timing] line confirms the session was spawned via the CCD path. The [chromeFileUpload] line shows the real INVALID_SESSION error that's then re-wrapped as the misleading user-facing message. User-facing error returned to the SKILL: 4. Wait for the cron to fire. file_upload returns the rejection error 100% of the time, regardless of file location. I traced the root cause in /Applications/Claude.app/Contents/Resources/app.asar → .vite/build/index.js: Gv only calls Ci.getSession() (cowork manager); CCD session IDs return null; Bcr wraps the thrown error as the generic catch-all message. The CCD buildSessionStartEvent schema (OXt) also explicitly drops userSelectedFolders / userSelectedFiles even when set on the scheduled-task record.

  1. Surface the real INVALID_SESSION error to the user instead of masking it as "only files the user has shared". Even a one-line addition like "(INVALID_SESSION: this session manager isn't recognized by file_upload; this may be a CCD scheduled task)" would have saved hours of dead-end debugging.

Root Cause

I traced the root cause in /Applications/Claude.app/Contents/Resources/app.asar → .vite/build/index.js: Gv only calls Ci.getSession() (cowork manager); CCD session IDs return null; Bcr wraps the thrown error as the generic catch-all message. The CCD buildSessionStartEvent schema (OXt) also explicitly drops userSelectedFolders / userSelectedFiles even when set on the scheduled-task record.

Fix Action

Fix / Workaround

Workaround in use: the affected task (tb-prep---heidi, daily 5 AM Heidi audio prep) now creates per-patient Heidi session shells with names pre-filled, then sends a desktop notification telling the user how many shells need manual audio upload + template application. The user opens each in their browser and does the file pick + template by hand.

Code Example

From ~/Library/Logs/Claude/main.log (test run 2026-05-28):

2026-05-28 11:31:32 [info] Starting local session local_2baaad08-b19c-4a36-8565-fbf84e649d70 in /Users/mmhw/Downloads/MO
2026-05-28 11:31:33 [info] Mapping internal session local_2baaad08-... to CLI session 24635ca6-7c44-4fcd-afe6-2dc61c073d1f
2026-05-28 11:31:36 [info] [CCD start-timing] local_2baaad08-... preflight=801ms ... total_to_assistant=4343ms
...
2026-05-28 11:33:20 [warn] uploadLocalFile: unknown local agent mode session local_2baaad08-b19c-4a36-8565-fbf84e649d70
2026-05-28 11:33:20 [warn] [chromeFileUpload] rejected path for session local_2baaad08-b19c-4a36-8565-fbf84e649d70: /Users/mmhw/Downloads/MO/Standard Audio - Heidi.m4a ([INVALID_SESSION] Unknown session: local_2baaad08-b19c-4a36-8565-fbf84e649d70)

The [CCD start-timing] line confirms the session was spawned via the CCD path. The [chromeFileUpload] line shows the real INVALID_SESSION error that's then re-wrapped as the misleading user-facing message.

User-facing error returned to the SKILL:
> Cannot upload "/Users/mmhw/Downloads/MO/Standard Audio - Heidi.m4a": only files the user has shared with this session can be uploaded.
RAW_BUFFERClick to expand / collapse

Preflight Checklist

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

What's Wrong?

mcp__Claude_in_Chrome__file_upload rejects every file path when called from a Claude Code Desktop scheduled task, with a misleading error message:

Cannot upload "/path/to/file": only files the user has shared with this session can be uploaded.

The real cause (from main.log) is INVALID_SESSION, not a permission/sharing issue. Claude Desktop has two parallel session managers — CCD (used by scheduled tasks) and cowork (used by interactive chat) — and the Chrome MCP file_upload validator (Gv in app.asar) only consults the cowork manager (Ci). For CCD session IDs, Ci.getSession() returns null, so the validator throws [INVALID_SESSION] Unknown session: ... before ever reading the allowlist. The catch wrapper (Bcr / chromeFileUpload) re-emits this as the generic "shared with this session" message the user sees.

This makes file_upload structurally unusable from any CCD scheduled task. No permission/folder/sharing config the user can set will fix it — the session is rejected before the allowlist is consulted.

What Should Happen?

Either:

(a) file_upload should succeed for CCD scheduled-task sessions the same way it does for interactive cowork sessions — by having Gv consult both session managers (ln and Ci), and sourcing the allowlist for CCD sessions from the scheduled-task record's userSelectedFolders field (which is already preserved by the JSON writer but never read);

OR at minimum

(b) the error should surface the real INVALID_SESSION reason instead of masking it as "only files the user has shared". The current message sent me down hours of dead-end debugging trying to "share" the file in every conceivable way (which is impossible for CCD sessions — the validator throws before the allowlist is even checked).

Error Messages/Logs

From ~/Library/Logs/Claude/main.log (test run 2026-05-28):

2026-05-28 11:31:32 [info] Starting local session local_2baaad08-b19c-4a36-8565-fbf84e649d70 in /Users/mmhw/Downloads/MO
2026-05-28 11:31:33 [info] Mapping internal session local_2baaad08-... to CLI session 24635ca6-7c44-4fcd-afe6-2dc61c073d1f
2026-05-28 11:31:36 [info] [CCD start-timing] local_2baaad08-... preflight=801ms ... total_to_assistant=4343ms
...
2026-05-28 11:33:20 [warn] uploadLocalFile: unknown local agent mode session local_2baaad08-b19c-4a36-8565-fbf84e649d70
2026-05-28 11:33:20 [warn] [chromeFileUpload] rejected path for session local_2baaad08-b19c-4a36-8565-fbf84e649d70: /Users/mmhw/Downloads/MO/Standard Audio - Heidi.m4a ([INVALID_SESSION] Unknown session: local_2baaad08-b19c-4a36-8565-fbf84e649d70)

The [CCD start-timing] line confirms the session was spawned via the CCD path. The [chromeFileUpload] line shows the real INVALID_SESSION error that's then re-wrapped as the misleading user-facing message.

User-facing error returned to the SKILL:
> Cannot upload "/Users/mmhw/Downloads/MO/Standard Audio - Heidi.m4a": only files the user has shared with this session can be uploaded.

Steps to Reproduce

  1. Have Claude Desktop running on macOS with the Claude in Chrome extension installed + connected + authenticated.
  2. Create a CCD scheduled task — either via the /schedule skill, or by adding an entry to ~/Library/Application Support/Claude/claude-code-sessions/<workspace>/scheduled-tasks.json with cwd, cronExpression, and filePath pointing to a SKILL.md.
  3. The SKILL.md should: open any web page containing an <input type="file"> element via mcp__Claude_in_Chrome__navigate, find the input via mcp__Claude_in_Chrome__find, then call: mcp__Claude_in_Chrome__file_upload({ paths: ["/Users/<you>/Downloads/anyfile.m4a"], ref: "<ref from find>", tabId: <tabId> })
  4. Wait for the cron to fire. file_upload returns the rejection error 100% of the time, regardless of file location.

Things I tried that did NOT fix it (all empirically verified):

  • Adding userSelectedFolders: ["/Users/.../Downloads/MO"] to the task record in scheduled-tasks.json (preserved on disk; never propagated to the spawned CCD session JSON; validator throws INVALID_SESSION before reading allowlist anyway)
  • Moving the file to /tmp, ~/.claude/, or the task's cwd
  • @/folder mention in chat
  • Restarting Claude Desktop

I traced the root cause in /Applications/Claude.app/Contents/Resources/app.asar → .vite/build/index.js: Gv only calls Ci.getSession() (cowork manager); CCD session IDs return null; Bcr wraps the thrown error as the generic catch-all message. The CCD buildSessionStartEvent schema (OXt) also explicitly drops userSelectedFolders / userSelectedFiles even when set on the scheduled-task record.

Claude Model

Opus

Is this a regression?

Yes, this worked in a previous version

Last Working Version

2.1.149

Claude Code Version

Claude Code running inside Claude Desktop 1.9255.2

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

Workaround in use: the affected task (tb-prep---heidi, daily 5 AM Heidi audio prep) now creates per-patient Heidi session shells with names pre-filled, then sends a desktop notification telling the user how many shells need manual audio upload + template application. The user opens each in their browser and does the file pick + template by hand.

Three suggested fixes ranked smallest → largest scope:

  1. Surface the real INVALID_SESSION error to the user instead of masking it as "only files the user has shared". Even a one-line addition like "(INVALID_SESSION: this session manager isn't recognized by file_upload; this may be a CCD scheduled task)" would have saved hours of dead-end debugging.

  2. Have Gv consult both session managers (ln and Ci). For CCD sessions, source the allowlist from the scheduled-task record's userSelectedFolders field (already preserved by the JSON writer; just never read on the spawn path).

  3. Unify the spawn paths so CCD buildSessionStartEvent carries userSelectedFolders / userSelectedFiles through the same as cowork's, registers CCD sessions in a unified registry, and lets Gv work uniformly.

Relevant files for engineering:

  • /Applications/Claude.app/Contents/Resources/app.asar → .vite/build/index.js (functions Gv, Bcr, OXt, Ci, ln, CCD vs cowork buildSessionStartEvent)
  • ~/Library/Logs/Claude/main.log (the [chromeFileUpload] rejected path warnings)
  • ~/Library/Application Support/Claude/claude-code-sessions/<workspace>/scheduled-tasks.json (CCD task records)
  • ~/Library/Application Support/Claude/claude-code-sessions/<workspace>/local_<id>.json (CCD session JSON — note userSelectedFolders key absent)
  • ~/Library/Application Support/Claude/local-agent-mode-sessions/<workspace>/local_<id>.json (cowork session JSON — userSelectedFolders: [] present as explicit empty array)

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING