📝 Description
On origin/develop, Manager API calls made from the React Native app can be rejected because the provider query parameter is sent as 1/ instead of 1.
The observed failing request is:
GET https://manager.api.live.ledger.com/api/get_device_version?target_id=858783748&provider=1/
Manager API responds with HTTP 400:
Invalid value for: query parameter provider
This appears to be a regression from the Axios to fetch / DmkNetworkClient refactor. The current fetch path builds a URL and later sends url.toString(). In React Native, the built-in URL implementation has known serialization issues where an extra trailing slash can be appended to URLs that already contain query parameters. The previous Axios path did not go through that React Native URL.toString() serialization path.
🙁 Actual Behavior
A device action that needs firmware/device metadata fails when getDeviceVersion calls Manager API.
Observed logs:
[device-session-refresher] Refresh skipped: device is busy
[DmkNetworkClient] HTTP error {method: 'GET', url: 'https://manager.api.live.ledger.com/api/get_device_version?target_id=858783748&provider=1/', status: 400, statusText: '', responseBody: 'Invalid value for: query parameter provider'}
[HttpManagerApiDataSource] getDeviceVersion failed {error: {...}, runtimeBodyGlobals: {...}}
[UninstallAppDeviceAction] [XStateDeviceAction] State: Error
[mobile.deviceAction] error { status: 'error', error: { _tag: 'FetchError', ... responseBody: 'Invalid value for: query parameter provider' } }
The important part is that the outgoing query parameter is provider=1/, so Manager API parses it as an invalid provider value.
🤩 Expected Behavior
The Manager API request should send the configured provider as a valid numeric query value:
GET https://manager.api.live.ledger.com/api/get_device_version?target_id=858783748&provider=1
getDeviceVersion should not fail with Invalid value for: query parameter provider.
🎬 Steps to Reproduce
- Check out
origin/develop (70106c177 at the time this was observed).
- Run the React Native mobile app on Android in development mode.
- Connect a Ledger device and trigger a device action that calls
getDeviceVersion via Manager API, for example uninstalling an app.
- Observe that
DmkNetworkClient logs a GET request to /api/get_device_version with provider=1/ and Manager API returns HTTP 400.
Additional verification:
https://manager.api.live.ledger.com/api/get_device_version?target_id=858783748&provider=1 is accepted by Manager API.
https://manager.api.live.ledger.com/api/get_device_version?target_id=858783748&provider=1/ returns the same HTTP 400 error seen in the app.
🧑💻 Context
This blocks device actions that depend on Manager API metadata in the React Native app.
Suspected root cause:
HttpManagerApiDataSource.getDeviceVersion() passes provider: this._provider correctly.
DmkNetworkClientHelpers.buildUrl() serializes query params manually, but still returns new URL(...).
DmkNetworkClient.request() sends url.toString() to fetch.
- React Native's
URL implementation can append an unwanted trailing slash when serializing URLs with query strings.
There was already a React Native compatibility fix that avoided URLSearchParams.set, but the remaining URL object serialization can still corrupt the final request URL. A likely fix is to avoid React Native's URL object for final request serialization and return/send a manually assembled string instead.
🖥️ Your Environment
- DMK Version:
origin/develop at 70106c177 when observed
- Ledger Device Model: Unknown from logs
- Ledger Device OS Version: Unknown from logs
- Connection Method: React Native Android app, likely Bluetooth / RN transport
- Application Name and Version: Uninstall app device action path
- Browser Name and Version: Not applicable
- Operating System and Version: Android app in React Native development mode
- Project Link: https://github.com/LedgerHQ/device-sdk-ts
📝 Description
On
origin/develop, Manager API calls made from the React Native app can be rejected because theproviderquery parameter is sent as1/instead of1.The observed failing request is:
Manager API responds with HTTP 400:
This appears to be a regression from the Axios to fetch /
DmkNetworkClientrefactor. The current fetch path builds aURLand later sendsurl.toString(). In React Native, the built-inURLimplementation has known serialization issues where an extra trailing slash can be appended to URLs that already contain query parameters. The previous Axios path did not go through that React NativeURL.toString()serialization path.🙁 Actual Behavior
A device action that needs firmware/device metadata fails when
getDeviceVersioncalls Manager API.Observed logs:
The important part is that the outgoing query parameter is
provider=1/, so Manager API parses it as an invalid provider value.🤩 Expected Behavior
The Manager API request should send the configured provider as a valid numeric query value:
getDeviceVersionshould not fail withInvalid value for: query parameter provider.🎬 Steps to Reproduce
origin/develop(70106c177at the time this was observed).getDeviceVersionvia Manager API, for example uninstalling an app.DmkNetworkClientlogs a GET request to/api/get_device_versionwithprovider=1/and Manager API returns HTTP 400.Additional verification:
https://manager.api.live.ledger.com/api/get_device_version?target_id=858783748&provider=1is accepted by Manager API.https://manager.api.live.ledger.com/api/get_device_version?target_id=858783748&provider=1/returns the same HTTP 400 error seen in the app.🧑💻 Context
This blocks device actions that depend on Manager API metadata in the React Native app.
Suspected root cause:
HttpManagerApiDataSource.getDeviceVersion()passesprovider: this._providercorrectly.DmkNetworkClientHelpers.buildUrl()serializes query params manually, but still returnsnew URL(...).DmkNetworkClient.request()sendsurl.toString()tofetch.URLimplementation can append an unwanted trailing slash when serializing URLs with query strings.There was already a React Native compatibility fix that avoided
URLSearchParams.set, but the remainingURLobject serialization can still corrupt the final request URL. A likely fix is to avoid React Native'sURLobject for final request serialization and return/send a manually assembled string instead.🖥️ Your Environment
origin/developat70106c177when observed