Skip to content

After connecting to Feather ESP32-S3 in Bluetooth, no file functions seem to work #372

Closed

Description

@ericzundel

CircuitPython Version

Adafruit CircuitPython 9.2.8 on 2025-05-28; Adafruit Feather ESP32S3 No PSRAM with ESP32S3
Board ID:adafruit_feather_esp32s3_nopsram

Note: I'm running in the latest Chrome on Windows 11.

When I connect via Bluetooth using the [learn.adafruit.com instructions](https://learn.adafruit.com/wirelessly-code-your-bluetooth-device-with-circuitpython/device-setup) 

I can see the serial console output, but none of the file functions seem to work. I get a spinning blinka icon and nothing in the JavaScript console.  

I've tried new, open, save as. Maybe also a clue: using Ctrl-C in the serial window also does nothing.

Workflow(s)

BLE

Browser(s)

Version 139.0.7258.155 (Official Build) (64-bit)

Console Log

Initializing File Transfer Client...
index.js:112 Connected!
index.js:112 Received: input: 
index.js:112  
index.js:112 None
index.js:112 
index.js:112 

index.js:112 Jiggle!

(the Jiggle! messages are from the script loaded on my CircuitPython device that output every few seconds)

Steps

  1. Connect with the BLE workflow.
  2. The connec dialog pops down on successful connection
  3. Try hitting the Open button at the top left
Image

Description

No response

Additional information

No response

Activity

  1. ericzundel commented on Sep 8, 2025

    @ericzundel
    ContributorAuthor

    I know there were just changes to the ble.js workflow. I reproduced this from main at commit 77e98ea today in my local development environment.

  2. ericzundel commented on Sep 8, 2025

    @ericzundel
    ContributorAuthor

    When I try the 'Open' button, it seems like listDir() in BLEFileTransferClient from @adafruit/ble-file-transfer-js is where the hang is occurring. I tracked it down by adding this patch:

    diff --git a/js/common/ble-file-transfer.js b/js/common/ble-file-transfer.js
    index fd7abf9..e69cabf 100644
    --- a/js/common/ble-file-transfer.js
    +++ b/js/common/ble-file-transfer.js
    @@ -38,6 +38,13 @@ class FileTransferClient extends BLEFileTransferClient {
    
             return versionInfo;
         }
    +
    +    async listDir(arg) {
    +        console.log("Calling listDir()");
    +        result = await super.listDir(arg);
    +        console.log("listDir() returned: ", result);
    +        return result
    +    }
     }
    
     export {FileTransferClient};
    \ No newline at end of file
    

    Console shows:

    ble.js:216 Initializing File Transfer Client...  
    workflow.js:118 Connected!
    ble-file-transfer.js:43 Calling listDir()
    
  3. ericzundel commented on Sep 8, 2025

    @ericzundel
    ContributorAuthor
        // Returns a list of tuples, one tuple for each file or directory in the given path
        async listDir(path) {
            await this.checkConnection();
            let encoded = new TextEncoder().encode(path);
            var header = new ArrayBuffer(4);
            var view = new DataView(header);
            view.setUint8(0, LISTDIR_COMMAND);
            // Offset 1 is reserved
            view.setUint16(2, encoded.byteLength, true);
            await this._write(header);
            await this._write(encoded);
    
            let p = new Promise((resolve, reject) => {
                this._resolve = resolve;
                this._reject = reject;
            });
            return p;
        }
    

    I tried debugging into adafruit-ble-file-transfer.js some, but only found that the Event Listener callback registered for 'characteristicvaluechanged' doesn't seem to be getting called.

  4. ericzundel commented on Sep 8, 2025

    @ericzundel
    ContributorAuthor

    So, in summary, the serial characteristic seems to be working, but the file transfer characteristic isn't.

  5. makermelissa commented on Sep 9, 2025

    @makermelissa
    Collaborator

    I wonder if this is related to the ESP32-S3 BLE implementation (though I doubt it). I'm not experiencing exactly the same thing with an nRF52840 board. It shows files, but has other issues.

  6. ericzundel commented on Sep 9, 2025

    @ericzundel
    ContributorAuthor

    I just ordered a nrf52840 board so we'll see if that works with Windows when it comes in.

  7. makermelissa commented on Sep 9, 2025

    @makermelissa
    Collaborator

    Ok, I also have ESP32-S3 boards, so I'll try testing with those.

  8. ericzundel commented on Sep 21, 2025

    @ericzundel
    ContributorAuthor

    I just hooked up my nrf52840 board and the behavior was the same. The UI displays the blinka 'busy' animation and never returns. My microprocessor occasionally flashes a green light. My python code is just

    import time
    
    while True:
        print("Hello World")
        time.sleep(10)
    

    boot_out.txt

    Adafruit CircuitPython 9.2.9 on 2025-09-07; Adafruit Feather nRF52840 Express with nRF52840
    Board ID:feather_nrf52840_express
    UID:70A585A5F1E6326F
    

    Here's what I see right after connecting in the serial window:

    Requesting device. Cancel if empty and try existing
    
    connecting to CIRCUITPY5239
    
    connected
    
    disconnected
    

    The immediate 'disconnected' seems to indicate that something is going wrong.

  9. makermelissa commented on Sep 24, 2025

    @makermelissa
    Collaborator

    I've was able to reproduce the issue, but only narrow it down where it's happening a little (it still disconnects, but control is returned to user).

  10. makermelissa commented on Sep 28, 2025

    @makermelissa
    Collaborator

    Are you able to do any read operations (i.e. opening a file)? If write only, I will close this in favor of #377.

  11. ericzundel commented on Sep 30, 2025

    @ericzundel
    ContributorAuthor
  12. makermelissa commented on Oct 1, 2025

    @makermelissa
    Collaborator

    Check the console for errors (right click somewhere, choose inspect, then click the console tab. I think I fixed some of the issues, but a specific error code would be helpful. In the console output of the initial issue above, it doesn't seem to indicate any errors.

  13. ericzundel commented on Oct 15, 2025

    @ericzundel
    ContributorAuthor

    We may be getting a bit far away from the original bug report.

    Here's what I see in the today when I tried to connect with Bluetooth again on Windows to the nrf52840_express. This time, I'm not even attempting to open a file.

    In the Serial window of the code.circuitpython.org website are the messages:

    Requesting device. Cancel if empty and try existing
    
    Attempting to connect to CIRCUITPY5239...
    
    Connected to CIRCUITPY5239
    
    disconnected
    

    The console shows as follows:

    Image
    Loading setting editor-visible with value null
    index.js:14 Loading setting terminal-visible with value true
    index.js:118 34 49 599 441 17.333333333333332 9
    index.js:118 Load different workflow
    index.js:112 Requesting any Bluetooth device...
    index.js:112 > Requested CIRCUITPY5239
    index.js:112 Watching advertisements from "CIRCUITPY5239"...
    index.js:112 If no advertisements are received, make sure the device is powered on and in range. You can also try resetting the device.
    index.js:112 > Received advertisement from "CIRCUITPY5239"...
    index.js:112 Connecting to GATT Server from "CIRCUITPY5239"...
    index.js:112 > Bluetooth device "CIRCUITPY5239 connected.
    index.js:112 connected BluetoothRemoteGATTServer {device: BluetoothDevice, connected: true}
    index.js:112 (2) [BluetoothRemoteGATTService, BluetoothRemoteGATTService]
    index.js:112 Initializing File Transfer Client...
    index.js:40 caught connection error NetworkError: Authentication failed. undefined
    index.js:112 NetworkError: Connection Error: Connection attempt failed. undefined
    index.js:112 Connected!
    index.js:112
    

    There is an exception being caught: NetworkError: Authentication failed

    I went through and re ran it on my development server which gives better filenames anline numbers

    Image
    ble.js: 175 Watching advertisements from "CIRCUITPY5239"...
    ble.js:176 If no advertisements are received, make sure the device is powered on and in range. You can also try resetting the device.
    ble.js:148 > Received advertisement from "CIRCUITPY5239"...
    ble.js:151 Connecting to GATT Server from "CIRCUITPY5239"...
    ble.js:162 > Bluetooth device "CIRCUITPY5239 connected.
    ble.js:204 connected BluetoothRemoteGATTServer {device: BluetoothDevice, connected: true}connected: falsedevice: BluetoothDevice {id: 'y/31mbCifQ/dIhZT+CsaZg==', name: 'CIRCUITPY5239', gatt: BluetoothRemoteGATTServer, ongattserverdisconnected: null, watchingAdvertisements: false, …}[[Prototype]]: BluetoothRemoteGATTServer
    ble.js:209 (2) [BluetoothRemoteGATTService, BluetoothRemoteGATTService]0: BluetoothRemoteGATTService {device: BluetoothDevice, uuid: '0000febb-0000-1000-8000-00805f9b34fb', isPrimary: true}1: BluetoothRemoteGATTService {device: BluetoothDevice, uuid: 'adaf0001-4369-7263-7569-74507974686e', isPrimary: true}length: 2[[Prototype]]: Array(0)
    ble.js:214 Initializing File Transfer Client...
    adafruit-ble-file-transfer.js:80 caught connection error NetworkError: Authentication failed. undefined
    workflow.js:106 onDisconnected called in workflow
    ble.js:110 NetworkError: GATT Server is disconnected. Cannot retrieve services. (Re)connect first with `device.gatt.connect`. undefined
    workflow.js:119 Connected!
    

    I believe I have all the permissions turned on in Chrome that I need. I can see bluetooth devices come up in the connect dialog when I try to connect and I see my devices

    Image Image
  14. added
    in betaFeature or bug fix is available on code-beta.circuitpython.org
    on Apr 30, 2026
  15. makermelissa-ai-assistant commented on Jun 17, 2026

    @makermelissa-ai-assistant
    Contributor

    @ericzundel coming back to this — there's been progress that we
    should ground-truth against your repro before chasing anything else.

    What changed

    While tracking #460, I found a CircuitPython firmware regression that
    explains the BLE-FT-side disconnect / silent-failure family in this
    issue (and was the root cause of #376 / #10972). When USB Mass Storage
    is enabled on the board — the default on most boards, regardless of
    whether any host is actually mounted — the firmware was holding the
    internal filesystem lock in a way that made BLE FT writes return
    status code 2 (General Error) instead of either succeeding or
    returning a useful read-only error. From the JS side it surfaces as
    "connect ok, file ops hang / disconnect" — which is exactly what you
    were seeing.

    The fix is
    adafruit/circuitpython#11048,
    merged 2026-06-10 (commit c955e48). It explicitly lets BLE File
    Transfer (and web workflow) bypass that lock while it holds its own
    write lock.

    Caveat — not in a tagged release yet

    Same caveat as #460: latest stable is 10.2.1, latest pre-release is
    10.3.0-alpha.2 (2026-05-15), both predate the fix. To test it today
    you need the Absolute Newest per-commit snapshot off main —
    direct links for your two boards:

    • Feather ESP32-S3 No PSRAM (2026-06-15 snapshot, post-fix) —
      .uf2
      /
      .bin
    • Feather nRF52840 Express (the PR#11048 build itself, 2026-06-10) —
      .uf2

    These are dev builds — back up CIRCUITPY before flashing. The
    PRNNNNN in the filename is just whichever PR triggered that build
    job; the fix you care about is the firmware-tree state at
    c955e48 and newer.

    What we're hoping to learn

    Could you flash one of those onto the same board you were testing
    with, then re-run the BLE workflow on Windows (Chrome) and try to
    open / save a file? Two possible outcomes:

    1. It works — meaning the firmware bug above was the whole story
      for this issue, and we can probably close it once 10.3.0-alpha.3
      ships so the fix is in a tagged release.
    2. Open/save still fail, but the error in the console is now
      different
      — almost certainly NetworkError: Authentication failed from your 2025-10-15 update. That's a real Web Bluetooth
      pairing issue on Windows that's separate from the firmware bug;
      the BLE FT characteristics on CircuitPython require an encrypted
      link, and Chrome on Windows can't always trigger the OS pairing
      prompt from the chooser. The workaround there is to pair the
      board through Windows Settings → Bluetooth & devices first,
      then connect from the web editor.

    Either way, the next step depends on which one you see, so a fresh
    console capture after flashing the snapshot would be really helpful.
    Thanks for sticking with this.

  16. makermelissa commented on Jun 17, 2026

    @makermelissa
    Collaborator

    Merged in #515

  17. ericzundel commented on Jun 28, 2026

    @ericzundel
    ContributorAuthor

    I tried the linked .uf2 file on my feather esp32-s3 and unfortunately, the same experience. I also tried the 10.3.0-alpha.3 release.

    Here's what's in the inspector console:

    Requesting any Bluetooth device...
    index.js:183 > Requested CIRCUITPYc3b7de
    index.js:183 Watching advertisements from "CIRCUITPYc3b7de"...
    index.js:183 If no advertisements are received, make sure the device is powered on and in range. You can also try resetting the device.
    index.js:183 > Received advertisement from "CIRCUITPYc3b7de"...
    index.js:183 Connecting to GATT Server from "CIRCUITPYc3b7de"...
    index.js:183 > Bluetooth device "CIRCUITPYc3b7de connected.
    index.js:183 connected BluetoothRemoteGATTServer
    index.js:173 onDisconnected called in workflow
    index.js:183 NetworkError: GATT Server is disconnected. Cannot retrieve services. (Re)connect first with `device.gatt.connect`. undefined
    index.js:183 Initializing File Transfer Client...
    index.js:85 caught connection error NetworkError: Failed to execute 'getPrimaryService' on 'BluetoothRemoteGATTServer': GATT Server is disconnected. Cannot retrieve services. (Re)connect first with `device.gatt.connect`.
        at AR.checkConnection (index.js:85:3848)
        at AR.bond (index.js:85:4695)
        at $Y.switchToDevice (index.js:183:7237)
        at async $Y.r (index.js:183:5797) NetworkError: Failed to execute 'getPrimaryService' on 'BluetoothRemoteGATTServer': GATT Server is disconnected. Cannot retrieve services. (Re)connect first with `device.gatt.connect`.
        at AR.checkConnection (https://code.circuitpython.org/assets/js/index.js:85:3848)
        at AR.bond (https://code.circuitpython.org/assets/js/index.js:85:4695)
        at $Y.switchToDevice (https://code.circuitpython.org/assets/js/index.js:183:7237)
        at async $Y.r (https://code.circuitpython.org/assets/js/index.js:183:5797)
    index.js:183 NetworkError: Failed to execute 'getPrimaryService' on 'BluetoothRemoteGATTServer': GATT Server is disconnected. Cannot retrieve services. (Re)connect first with `device.gatt.connect`.
        at $Y.connectToSerial (index.js:183:4220)
        at $Y.switchToDevice (index.js:183:7255)
        at async $Y.r (index.js:183:5797) "NetworkError: Failed to execute 'getPrimaryService' on 'BluetoothRemoteGATTServer': GATT Server is disconnected. Cannot retrieve services. (Re)connect first with `device.gatt.connect`.\n    at $Y.connectToSerial (https://code.circuitpython.org/assets/js/index.js:183:4220)\n    at $Y.switchToDevice (https://code.circuitpython.org/assets/js/index.js:183:7255)\n    at async $Y.r (https://code.circuitpython.org/assets/js/index.js:183:5797)"
    index.js:173 Connected!
    index.js:85 Reading version info
    index.js:85 caught connection error NetworkError: Failed to execute 'getPrimaryService' on 'BluetoothRemoteGATTServer': GATT Server is disconnected. Cannot retrieve services. (Re)connect first with `device.gatt.connect`.
        at AR.checkConnection (index.js:85:3848)
        at AR.readFile (index.js:85:5665)
        at AR.versionInfo (index.js:85:12362)
        at lk._getDeviceInfo (index.js:49:20675)
        at lk.open (index.js:49:21615)
        at $Y.showInfo (index.js:183:9555)
        at index.js:189:22787 NetworkError: Failed to execute 'getPrimaryService' on 'BluetoothRemoteGATTServer': GATT Server is disconnected. Cannot retrieve services. (Re)connect first with `device.gatt.connect`.
        at AR.checkConnection (https://code.circuitpython.org/assets/js/index.js:85:3848)
        at AR.readFile (https://code.circuitpython.org/assets/js/index.js:85:5665)
        at AR.versionInfo (https://code.circuitpython.org/assets/js/index.js:85:12362)
        at lk._getDeviceInfo (https://code.circuitpython.org/assets/js/index.js:49:20675)
        at lk.open (https://code.circuitpython.org/assets/js/index.js:49:21615)
        at $Y.showInfo (https://code.circuitpython.org/assets/js/index.js:183:9555)
        at https://code.circuitpython.org/assets/js/index.js:189:22787
    index.js:85 caught write error TypeError: Cannot read properties of null (reading 'writeValueWithoutResponse')
        at AR._write (index.js:85:4401)
        at AR.readFile (index.js:85:5951)
        at async AR.versionInfo (index.js:85:12351)
        at async $Y.showBusy (index.js:173:901)
        at async lk._getDeviceInfo (index.js:49:20637)
        at async lk.open (index.js:49:21604)
        at async $Y.showInfo (index.js:183:9533) TypeError: Cannot read properties of null (reading 'writeValueWithoutResponse')
        at AR._write (https://code.circuitpython.org/assets/js/index.js:85:4401)
        at AR.readFile (https://code.circuitpython.org/assets/js/index.js:85:5951)
        at async AR.versionInfo (https://code.circuitpython.org/assets/js/index.js:85:12351)
        at async $Y.showBusy (https://code.circuitpython.org/assets/js/index.js:173:901)
        at async lk._getDeviceInfo (https://code.circuitpython.org/assets/js/index.js:49:20637)
        at async lk.open (https://code.circuitpython.org/assets/js/index.js:49:21604)
        at async $Y.showInfo (https://code.circuitpython.org/assets/js/index.js:183:9533)
    index.js:85 caught write error TypeError: Cannot read properties of null (reading 'writeValueWithoutResponse')
        at AR._write (index.js:85:4401)
        at AR.readFile (index.js:85:5972)
        at async AR.versionInfo (index.js:85:12351)
        at async $Y.showBusy (index.js:173:901)
        at async lk._getDeviceInfo (index.js:49:20637)
        at async lk.open (index.js:49:21604)
        at async $Y.showInfo (index.js:183:9533) TypeError: Cannot read properties of null (reading 'writeValueWithoutResponse')
        at AR._write (https://code.circuitpython.org/assets/js/index.js:85:4401)
        at AR.readFile (https://code.circuitpython.org/assets/js/index.js:85:5972)
        at async AR.versionInfo (https://code.circuitpython.org/assets/js/index.js:85:12351)
        at async $Y.showBusy (https://code.circuitpython.org/assets/js/index.js:173:901)
        at async lk._getDeviceInfo (https://code.circuitpython.org/assets/js/index.js:49:20637)
        at async lk.open (https://code.circuitpython.org/assets/js/index.js:49:21604)
        at async $Y.showInfo (https://code.circuitpython.org/assets/js/index.js:183:9533)
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    BLE WorkflowbugSomething isn't workingin betaFeature or bug fix is available on code-beta.circuitpython.org

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions