Skip to content

runBrowserLiveSession builds invalid mobile URLs: beta version strings and lowercased device_browser #383

Description

@PaataBug

Summary

Mobile Live sessions launched via runBrowserLiveSession fail on the dashboard with "Sorry, the OS and browser combination selected doesn't exist. Please reselect your OS and browser, and try again." Desktop sessions from the same tool work fine. There appear to be two separate causes, both in URL construction.

1. Beta version strings are passed through verbatim

For iPhone 15 Pro the Live device cache holds ["27 Beta", "17.0"]. The dashboard identifies those two options as 27.0 and 17.0 — visible in the device picker markup as data-id="iPhone 15 Pro-27.0" and data-id="iPhone 15 Pro-17.0".

resolveVersion returns the raw cache string, so buildMobileUrl emits os_version=27 Beta, which the dashboard cannot resolve.

  • desiredOSVersion: "latest"parseFloat("27 Beta") = 27, which beats 17 → os_version=27 Beta → rejected.

2. An unavailable version silently resolves to a distant one

desiredOSVersion: "26" (not offered on iPhone 15 Pro; it is offered on iPhone 15 non-Pro) misses exact matching, case-insensitive matching and major-version matching, then falls through to the fuzzy "closest numeric" branch in resolveVersion. That picks 27 Beta, because |27 - 26| < |17 - 26|.

The result is a broken URL whose only signal is a trailing Note: Os version 26 was not found. Using 27 Beta instead. appended to the response. Failing with the list of versions actually available for that device would be considerably more useful than silently substituting a beta build.

3. Suspected: device_browser is not normalised

In src/tools/live-utils/start-session.ts, the two builders differ:

// buildDesktopUrl — uses the cache-derived value
browser: e.browser,           // "Chrome"

// buildMobileUrl — uses the raw user-supplied enum
device_browser: args.browser, // "safari", lowercase

The mobile path never consults the device cache for the browser name, so it always sends the lowercase enum value. If the dashboard is case-sensitive on device_browser, every mobile session would fail regardless of the version.

This is unconfirmed, but it would explain an observation the version bugs above do not: a URL where os_version resolved correctly to 17.0 (a valid identifier for this device) was also rejected.

Reproduction

runBrowserLiveSession({
  platformType: "mobile",
  desiredOS: "ios",
  desiredOSVersion: "latest",
  desiredBrowser: "safari",
  desiredDevice: "iPhone 15 Pro",
  desiredURL: "https://example.com"
})

Returns a link of the form:

https://live.browserstack.com/dashboard#os=iOS&os_version=27+Beta&device=iPhone+15+Pro&device_browser=safari&url=https%3A%2F%2Fexample.com&scale_to_fit=true&speed=1&local=false&start=true

Opening it produces the combination error. The same call with desiredOSVersion: "26" produces an identical URL plus the substitution note.

For contrast, the desktop path works:

runBrowserLiveSession({ platformType: "desktop", desiredOS: "Windows", desiredOSVersion: "11",
  desiredBrowser: "chrome", desiredBrowserVersion: "latest", desiredURL: "https://example.com" })

(Worth noting that latest resolves to 154.0 dev there, a pre-release channel, which is a related surprise for anyone testing against what real users run.)

Expected behaviour

  1. Emit the version identifier the dashboard accepts, rather than the cache's display string.
  2. When the requested version is not available for the chosen device, fail with the available versions instead of substituting a different one — especially not a beta.
  3. Normalise device_browser the way the desktop builder normalises browser.

Environment

  • Hosted Remote MCP (https://mcp.browserstack.com/mcp), OAuth
  • Also reproduced against @browserstack/mcp-server@1.3.1 installed locally
  • Client: Claude Code
  • Device confirmed present and enabled in the picker (aria-disabled="false"), so this is not a plan or entitlement issue

Activity

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions