Skip to content

BLE: deviceQuery write can run before gatt.connect() completes, causing "Connection already in progress" on Windows/Linux #22

@rinchen

Description

@rinchen

Summary

On Windows 11 and Linux, BLE connection often fails with NetworkError: Connection already in progress when writing to the device. The failed to write to ble device log appears, and the connection either times out or reports a generic error.

Root cause

WebBleConnection.open() returns a connection object while initialization (including gatt.connect()) is still in progress. The library then runs deviceQuery() (which performs a BLE write) before the GATT connection has fully completed. On Windows and Linux, the Web Bluetooth stack rejects the write with "Connection already in progress" in that case.

So there is a race: the first BLE write happens before gatt.connect() has resolved.

Expected behavior

No BLE write (including deviceQuery()) should be performed until gatt.connect() has successfully completed. The library should await the GATT connection before issuing any write.

Actual behavior

  • open() returns; init continues async (e.g. gatt.connect(), then deviceQuery()).
  • deviceQuery() write is attempted while connection may still be establishing.
  • Browser throws NetworkError: Connection already in progress (or similar).
  • Callers see "failed to write to ble device" and connection fails or times out (e.g. after nudge/timeout logic in the app).

Environment

  • Platforms: Windows 11, Linux (reported by users of a desktop client using meshcore.js).
  • Context: Electron app using Web Bluetooth; WebBleConnection.open() then waiting for connected event before sending further commands.

Possible fix

In the BLE connection path, await gatt.connect() (and any other setup that must complete first) before calling deviceQuery() or any other BLE write. That would remove the race and prevent "Connection already in progress" on stricter platforms.

Workaround (for callers)

Callers can retry the connection once after a short delay when they see "Connection already in progress" or GATT init failures; that sometimes succeeds when the second attempt runs after the stack has settled. Fixing the race in the library would be the proper solution.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions