Skip to content

[BUG] Claude in Chrome file_upload rejects all scheduled-task sessions with misleading error (real cause: INVALID_SESSION) #63334

Description

@Operations-svg1

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//scheduled-tasks.json with cwd, cronExpression, and filePath pointing to a SKILL.md.
  3. The SKILL.md should: open any web page containing an 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//Downloads/anyfile.m4a"],
    ref: "",
    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//scheduled-tasks.json (CCD task records)
  • ~/Library/Application Support/Claude/claude-code-sessions//local_.json (CCD session JSON — note userSelectedFolders key absent)
  • ~/Library/Application Support/Claude/local-agent-mode-sessions//local_.json (cowork session JSON — userSelectedFolders: [] present as explicit empty array)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions