You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
After connecting to Feather ESP32-S3 in Bluetooth, no file functions seem to work #372
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()
// 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.
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.
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.
I'm not getting very far at all. For all I know, these are general windows
connectivity issues. When I try connecting through the OS bluetooth
settings first, I do see an error:
Uncaught (in promise) NetworkError: GATT Server is disconnected. Cannot
retrieve services. (Re)connect first with `device.gatt.connect`.
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.
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:
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
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
@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 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:
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.
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.
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)
Activity
ericzundel commentedon Sep 8, 2025
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.
ericzundel commentedon Sep 8, 2025
When I try the 'Open' button, it seems like
listDir()inBLEFileTransferClientfrom@adafruit/ble-file-transfer-jsis where the hang is occurring. I tracked it down by adding this patch:Console shows:
ericzundel commentedon Sep 8, 2025
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.
ericzundel commentedon Sep 8, 2025
So, in summary, the serial characteristic seems to be working, but the file transfer characteristic isn't.
makermelissa commentedon Sep 9, 2025
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.
ericzundel commentedon Sep 9, 2025
I just ordered a nrf52840 board so we'll see if that works with Windows when it comes in.
makermelissa commentedon Sep 9, 2025
Ok, I also have ESP32-S3 boards, so I'll try testing with those.
ericzundel commentedon Sep 21, 2025
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
boot_out.txt
Here's what I see right after connecting in the serial window:
The immediate 'disconnected' seems to indicate that something is going wrong.
makermelissa commentedon Sep 24, 2025
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).
makermelissa commentedon Sep 28, 2025
Are you able to do any read operations (i.e. opening a file)? If write only, I will close this in favor of #377.
ericzundel commentedon Sep 30, 2025
makermelissa commentedon Oct 1, 2025
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.
ericzundel commentedon Oct 15, 2025
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:
The console shows as follows:
There is an exception being caught:
NetworkError: Authentication failedI went through and re ran it on my development server which gives better filenames anline numbers
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
makermelissa-ai-assistant commentedon Jun 17, 2026
@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 FileTransfer (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:
.uf2
/
.bin
.uf2
These are dev builds — back up CIRCUITPY before flashing. The
PRNNNNNin the filename is just whichever PR triggered that buildjob; the fix you care about is the firmware-tree state at
c955e48and 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:
for this issue, and we can probably close it once 10.3.0-alpha.3
ships so the fix is in a tagged release.
different — almost certainly
NetworkError: Authentication failedfrom your 2025-10-15 update. That's a real Web Bluetoothpairing 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.
makermelissa commentedon Jun 17, 2026
Merged in #515
ericzundel commentedon Jun 28, 2026
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: