Skip to content

fix(ble): read ESPHome proxy pre-decoded GATT uuid (#229)#234

Merged
KristianP26 merged 1 commit into
devfrom
fix/229-esphome-gatt-uuid
Jun 12, 2026
Merged

fix(ble): read ESPHome proxy pre-decoded GATT uuid (#229)#234
KristianP26 merged 1 commit into
devfrom
fix/229-esphome-gatt-uuid

Conversation

@KristianP26

Copy link
Copy Markdown
Owner

#229 ESPHome proxy GATT crash: Cannot read properties of undefined (reading 'length')

Root cause

@2colors/esphome-native-api 1.3.6 passes every message through mapMessageByType(). For BluetoothGATTGetServicesResponse it strips the raw uuidList uint64 pair off each service/characteristic and replaces it with a pre-decoded uuid string. The Phase 2 GATT bridge still read ch.uuidList (now undefined) and passed it to esphomeUuidToString(), which ran .length on undefined and threw, aborting every GATT read over the proxy right after a successful connect + service discovery.

Why CI missed it

The old test fixture invented a uuidList shape that matched neither the real library nor raw google-protobuf, so it only exercised an imaginary contract. Green CI, crashing hardware. This was the first real-HW test of the GATT path.

Fix

  • Resolve the characteristic UUID from the library's uuid string; keep the uuidList [high, low] decoder as a fallback for other library versions.
  • Skip any characteristic whose UUID cannot be resolved instead of crashing the session; esphomeUuidToString() returns '' for a missing/empty list rather than throwing.
  • Test fixture rewritten to mirror the actual 1.3.6 output, plus a regression test for malformed entries.

No adapter changes. 1630 tests green, lint/tsc/prettier clean.

Closes nothing yet on purpose: stays open until the reporter confirms on the Beurer BF788.

@2colors/esphome-native-api 1.3.6 runs every message through
mapMessageByType(), which for BluetoothGATTGetServicesResponse strips the
raw uuidList uint64 pair off each service/characteristic and replaces it
with a pre-decoded `uuid` string. The Phase 2 GATT bridge still read
`ch.uuidList`, so esphomeUuidToString() ran `.length` on undefined and
threw "Cannot read properties of undefined (reading 'length')" right after
a successful connect and service discovery, aborting every GATT read over
the proxy.

Resolve the characteristic UUID from the library's `uuid` string, keeping
the uuidList [high, low] decoder as a fallback for other library versions,
and skip any characteristic whose UUID cannot be resolved instead of
crashing the whole session. esphomeUuidToString() now returns '' for a
missing/empty list rather than throwing.

The previous test fixture invented a uuidList shape that matched neither
the real library nor raw google-protobuf, so CI was green while real
hardware crashed. The fixture now mirrors the actual 1.3.6 output.
@KristianP26 KristianP26 merged commit c1079c7 into dev Jun 12, 2026
6 checks passed
@KristianP26 KristianP26 deleted the fix/229-esphome-gatt-uuid branch June 12, 2026 12:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant