file_upload tool rejects local filesystem paths despite schema advertising them

Status Open
Maintainer reply None cached
Activity 5 comments · opened Jun 17, 2026

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:

  1. The paths parameter works as documented (accepts absolute local filesystem paths), or
  2. The schema and description are updated to reflect the new files parameter API, with clear documentation on how to pass file contents from the MCP controller side.

View original on GitHub ↗

5 Comments

madesh24-svg · 4 months ago

Duplicate of #62232. Closing this issue — please track there.

madesh24-svg · 4 months ago

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_ENTRYPOINT is not claude-desktop). The error message is also different:

  • #62232: Cannot upload [path]: only files the user has shared with this session can be uploaded.
  • This issue: 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.

therealskoala · 2 months ago

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:

MCP error -32602: Input validation error: Invalid arguments for tool file_upload: [
  { "expected": "array", "code": "invalid_type", "path": ["paths"],
    "message": "Invalid input: expected array, received undefined" }
]

Note paths arrives undefined — the argument is stripped before validation runs. The same call nested inside browser_batch fails differently:

file_upload requires a non-empty `paths` array of files the user has shared with this session.

One surface sees paths undefined, the other sees it empty. That is consistent with the argument-sanitization root cause documented in #70328 (extension migrated to files:[{name,data}], client still advertises and sanitizes to paths) — 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 allowed after 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_upload entirely — generating an image in-page with canvas.toBlob() and POSTing it as multipart FormData to the same target endpoint — returns HTTP 200 and a valid blob URL:

POST /api/settings/upload-photo   (page context, session cookies attached)
  -> 200, application/json
  -> { url: "https://<store>.public.blob.vercel-storage.com/.../routetest-92a8daac.jpg" }

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 atob with InvalidCharacterError. upload_image is not a substitute either, as it only accepts an imageId from 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 explicit files param) would resolve this surface as well.

therealskoala · 2 months ago

Correction to my comment above. I claimed the paths argument 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_batch calls 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 paths schema 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:

  • I attributed this to the 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.
  • I listed the session file-sharing allowlist as ruled out via the outputs folder. I've since also tested a file in the session's own uploads folder — the location confirmed working in #63334 — and it fails identically. So the allowlist really is not involved.

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 stale and its original error message (file_upload no longer accepts host filesystem paths...) is a different surface from the paths: expected array, received undefined one.

alexspbmeister · 26 days ago

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 files parameter. If you are
seeing 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">, find for the ref, then file_upload with paths. 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.