Cursor's Simple Browser suddenly can't create/save or load files via File System Access API

Where does the bug appear (feature/product)?

Cursor IDE

Describe the Bug

Yesterday (or the day before) Cursor’s integrated Simple Browser allowed an application I’ve been working on to create files (save copies of a workspace within the application), and open said files to load old workspaces.

Since the latest update attempting to save anything resulted in a 0KB empty file, and loading (intact) files didn’t work, either. The issue only occurs when attempting to test the application in Cursor’s own browser; when testing using a desktop browser (Floorp or Chrome, for example), or a compiled version of my application for desktop, I can save files out and load files fine.

Steps to Reproduce

A HTML file that attempts to use a filepicker to get and read a file, or to save a file out, demonstrates the issue:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>FS Access API Test</title>
  <style>
    body {
      font-family: system-ui, sans-serif;
      margin: 2rem;
      line-height: 1.4;
    }

    .buttons {
      display: flex;
      gap: 0.75rem;
      margin-bottom: 1rem;
    }

    button {
      padding: 0.6rem 1rem;
      font: inherit;
      cursor: pointer;
    }

    pre {
      white-space: pre-wrap;
      word-break: break-word;
      border: 1px solid #ccc;
      padding: 1rem;
      min-height: 16rem;
      background: #f7f7f7;
    }
  </style>
</head>
<body>
  <h1>File System Access API Test</h1>
  <p>Use the buttons below to test open and save behavior in Cursor's Simple Browser or another browser.</p>

  <div class="buttons">
    <button id="load" type="button">Load File</button>
    <button id="save" type="button">Save File</button>
    <button id="clear" type="button">Clear Log</button>
  </div>

  <pre id="log" aria-live="polite"></pre>

  <script>
    const logEl = document.getElementById("log");

    function log(message) {
      logEl.textContent += message + "\n";
    }

    function logError(prefix, error) {
      const details = [
        prefix,
        error && error.name ? `name=${error.name}` : "",
        error && error.message ? `message=${error.message}` : "",
      ].filter(Boolean).join(" | ");
      log(details || prefix);
    }

    document.getElementById("clear").addEventListener("click", () => {
      logEl.textContent = "";
      log("Log cleared");
    });

    document.getElementById("load").addEventListener("click", async () => {
      try {
        log("Calling showOpenFilePicker...");
        const [handle] = await window.showOpenFilePicker();
        log("Got handle: " + handle.name);

        const file = await handle.getFile();
        log("Got file object");
        log("File size: " + file.size);

        const text = await file.text();
        log("Read file text");
        log("Content preview: " + text.slice(0, 200));
      } catch (error) {
        logError("Load error", error);
      }
    });

    document.getElementById("save").addEventListener("click", async () => {
      try {
        log("Calling showSaveFilePicker...");
        const handle = await window.showSaveFilePicker({
          suggestedName: "fs-access-api-test.txt",
        });
        log("Got handle: " + handle.name);

        const writable = await handle.createWritable();
        log("Got writable stream");

        await writable.write("Hello from FS Access API test");
        log("Write called");

        await writable.close();
        log("Stream closed - save complete");
      } catch (error) {
        logError("Save error", error);
      }
    });

    log("showOpenFilePicker: " + typeof window.showOpenFilePicker);
    log("showSaveFilePicker: " + typeof window.showSaveFilePicker);
  </script>
</body>
</html>

Expected Behavior

Chrome (working behaviour):

Creating/saving a file:

Calling showSaveFilePicker...
Got handle: fs-access-api-test.txt
Got writable stream
Write called
Stream closed - save complete

The file is written, and contains the text ‘Hello from FS Access API test’ in this case.

Opening a file:

Calling showOpenFilePicker...
Got handle: fs-access-api-test.txt
Got file object
File size: 29
Read file text
Content preview: Hello from FS Access API test

Cursor’s Simple Browser behaviour (non-functional):

Creating/saving a file

Calling showSaveFilePicker...
Got handle: fs-access-api-test.txt
Save error | name=NotAllowedError | message=Failed to execute 'createWritable' on 'FileSystemFileHandle': The request is not allowed by the user agent or the platform in the current context.

Loading a file:

Calling showOpenFilePicker...
Got handle: fs-access-api-test.txt
Load error | name=NotAllowedError | message=Failed to execute 'getFile' on 'FileSystemFileHandle': The request is not allowed by the user agent or the platform in the current context.

Operating System

Windows 10/11

Version Information

Version: 3.13.25 (system setup)
VS Code Extension API: 1.128.0
Commit: 31e8d61c448c7472e371505838a0fe34083dad50
Date: 2026-07-28T06:17:45.069Z
Layout: IDE
Build Type: Stable
Release Track: Default
Electron: 40.10.3
Chromium: 144.0.7559.236
Node.js: 24.15.0
V8: 14.4.258.32-electron.0
xterm.js: 6.1.0-beta.256
OS: Windows_NT x64 10.0.26200

Additional Information

I don’t know if this was an intentional change for security or unintentional, but it more or less ruins Cursor’s Simple Browser as a test environment for the tool I’m working on, if it won’t act like most browsers or consistently to how it behaved a few days before.
The lack of patch notes to explain the change, if this was intentional, led me down a small rabbit hole trying to fix what appeared to be a bug.

Does this stop you from using Cursor

No - Cursor works, but with this issue

Hey, thanks for the detailed report. The minimal repro and logs really helped.

This is a confirmed regression in 3.13.x. The File System Access API showSaveFilePicker and showOpenFilePicker in the built-in Simple Browser now hits a NotAllowedError on createWritable() and getFile(), which is why you get 0 KB files. It worked in 3.12.x.

The cause is a change in the built-in browser permissions tied to a recent security update. So it’s not something random on your side, and it’s not intended behavior specifically for FSA. It looks like a side effect. There isn’t a toggle to bring back the old behavior right now.

Workaround until it’s fixed: test the FSA flow in an external browser like Chrome or Floorp, or in the compiled desktop version of the app. Both work as you described.

I’ve reported the bug internally. I can’t share an ETA yet, but I’ll post an update in the thread as soon as I have one.