file_upload tool rejects local filesystem paths despite schema advertising them
Bug Description
The file_upload Claude-in-Chrome tool fails when provided with absolute local filesystem paths, despite its schema explicitly stating they are supported.
Schema (as advertised)
Tool description: "Upload one or multiple files from the local filesystem to a file input element on the page... The paths must be absolute file paths on the local machine."
paths parameter description: "The absolute paths to the files to upload. Can be a single file or multiple files."
Actual Behaviour
When calling file_upload with an absolute Windows path, the tool returns:
file_upload no longer accepts host filesystem paths. The MCP controller must read the file and pass its contents via the `files` parameter. If you are seeing this in Claude Desktop, update the desktop app.
Impact
The tool is advertised as enabling direct disk-to-browser file uploads with no token cost. Because the runtime rejects host paths, the MCP controller (Claude Code) is forced to read the file into context first — defeating the purpose entirely.
Environment
- Claude Code CLI (not Claude Desktop)
- Windows 11 Enterprise
- claude-in-chrome MCP extension
Expected Behaviour
Either:
- The
pathsparameter works as documented (accepts absolute local filesystem paths), or - The schema and description are updated to reflect the new
filesparameter API, with clear documentation on how to pass file contents from the MCP controller side.
5 Comments
Duplicate of #62232. Closing this issue — please track there.
Reopening — #62232 is not a confirmed fix. It is a proposed fix only, and it is scoped to macOS + Claude Desktop (
CLAUDE_CODE_ENTRYPOINT=claude-desktop, macOS 25.5.0).This issue reproduces on Windows 11 Enterprise + Claude Code CLI (
CLAUDE_CODE_ENTRYPOINTis notclaude-desktop). The error message is also different:Cannot upload [path]: only files the user has shared with this session can be uploaded.file_upload no longer accepts host filesystem paths. The MCP controller must read the file and pass its contents via the files parameter.The underlying cause may be related but the surface, error, and environment are distinct. Keeping open as a Windows/CLI-specific track.
Still reproducing as of 2026-08-06. Adding a Windows + Claude Desktop (Cowork mode) datapoint, since this is now marked
stale.A third distinct error signature
This surface fails at JSON-RPC schema validation, before the extension is ever reached:
Note
pathsarrivesundefined— the argument is stripped before validation runs. The same call nested insidebrowser_batchfails differently:One surface sees
pathsundefined, the other sees it empty. That is consistent with the argument-sanitization root cause documented in #70328 (extension migrated tofiles:[{name,data}], client still advertises and sanitizes topaths) — that analysis appears to apply to the Desktop/Cowork surface too, not just the CLI. #70328 was auto-closed as a duplicate of this issue, so this thread is now the only open track for a bug with three documented error variants across macOS/CLI and Windows/Desktop.Ruled out (each tested directly, not assumed)
| Hypothesis | Test | Result |
|---|---|---|
| Session file-sharing allowlist | Used a file in the session's own outputs folder | Same error |
| "Allow access to file URLs" toggle | That returns
-32000 Not allowedafter dispatch; this fails at validation | Not the cause || Multi-device routing | Two browsers connected (macOS + Windows); explicitly
select_browser'd the local Windows device | Same error || Stale local state | Restarted desktop app, extension, and rebooted the machine; only one browser connected after | Same error |
| Path formatting | Escaped backslashes, forward slashes, multiple files and folders | Same error |
The fault is in the tool, not the page
Bypassing
file_uploadentirely — generating an image in-page withcanvas.toBlob()and POSTing it as multipart FormData to the same target endpoint — returns HTTP 200 and a valid blob URL:Endpoint, auth and storage are all healthy. Only the tool's argument transport is broken.
Impact
Blocks a production workflow that publishes daily social posts for 21 restaurant clients across two scheduled tasks. Two consecutive days lost (2026-08-05, 2026-08-06), 0 accounts published.
There is no workaround on this surface. The only other route for getting file bytes into the page is base64 through model context, which is impractical (~150 KB per image) and unreliable — long strings fail
atobwithInvalidCharacterError.upload_imageis not a substitute either, as it only accepts animageIdfrom a screenshot or prior upload, not an arbitrary local path.The fix proposed in #70328 (convert
paths→files:[{name,data,mimeType}]in the passthrough, or stop stripping an explicitfilesparam) would resolve this surface as well.Correction to my comment above. I claimed the
pathsargument was "stripped before validation runs" / "lost in transit". That is wrong, and I don't want to leave a bad mechanism in the record for whoever debugs this.Further probing shows the argument arrives intact. Two
browser_batchcalls differing only in whether the file exists:| Path passed | Error returned |
|---|---|
| a file that exists (545,452 bytes) |
file_upload requires a non-empty paths array...|| a file that does not exist |
Cannot upload "C:\...\ZZ_DOES_NOT_EXIST_PROBE.jpg": only files this session is allowed to read can be uploaded.|The non-existent path is quoted back verbatim, so the argument is received, parsed and existence-checked. What actually happens is inverted: a non-existent path produces a loud, correct error, while an existing path passes validation and is then silently dropped from the array before upload. The failure is in the read/attach step, and the thrown exception is being flattened into a
pathsschema error.@jairomoreira296-hue reached the same conclusion independently on #84627 via a different route (missing file → correct error; hard-linked file → correct error; real readable file → schema error).
Two further corrections to my earlier comment:
files:[{name,data}]version-skew described in #70328. That may still be a real problem, but it does not explain the existence-flip above, so I'd treat it as a separate matter rather than the cause here.Also worth noting for this thread: the 2026-08-06 changelog entry "Claude in Chrome file uploads failing for files in the session's shared folders and outputs" (v1.26832.0) does not fix this. Retested after updating, same failure. @arjen-rave reported the same on #63334 the following day.
Full detail is now on #84627, which matches this exact error signature and has three independent reporters across macOS/CLI and Windows/Desktop. That's probably the better thread to consolidate on — this one is still labelled
staleand its original error message (file_upload no longer accepts host filesystem paths...) is a different surface from thepaths: expected array, received undefinedone.Still reproducing on 19 Sep 2026, with the exact error from the opening post.
Surface: Windows 11, Claude desktop app 2.2553.1.0, Cowork session driving the Claude in Chrome connector (not the CLI). Same message, verbatim:
file_upload no longer accepts host filesystem paths. The MCP controller must
read the file and pass its contents via the
filesparameter. If you areseeing this in Claude Desktop, update the desktop app.
The app is on the newest version offered, so "update the desktop app" has nowhere to go. This is also after v1.26832.0 (2026-08-06), whose changelog entry about file uploads does not address this signature.
One datapoint I haven't seen in this thread: the tool description has already been rewritten for the new access model, while the parameter list has not. The schema served to the model today is:
file_upload
paths (array of strings, required)
ref (string, required)
tabId (number, required)
and the description now reads "Only files the user has shared with this session (attachments, the session's outputs/uploads folders, or folders the user has connected) can be uploaded". So the prose moved to the new model and the contract did not. That asymmetry is probably the shortest statement of this bug: the error demands a parameter the caller cannot see or send, and no call shape can satisfy it.
Reproduction was trivial and page-independent - a blank page with an injected <input type="file">,
findfor the ref, then file_upload withpaths. Repeated with a second file from a different connected folder: identical refusal, so it is not about a particular file, folder or path shape.Practical impact here: an agent-driven workflow that attached invoice PDFs to a web application is dead, and there is no workaround on this surface - upload_image only takes a screenshot id, and base64 through model context is not viable for PDFs.