← reports

#2929 · Signed-in web links use an isolated browser

Bug Medium Effort: Low desktop open on GitHub 2026-09-02 · base eeaaa3e8d

Verdict: REPRODUCED · Root-cause confidence: high

1. TL;DR

BB sends each HTTP link to its in-app browser when the desktop browser exists and the default preference is on.

The in-app browser uses an Electron session that does not share the user's default browser session.

A link that needs the default browser session therefore opens in the wrong browser.

Two clean tests at the trusted base commit produced the same wrong target.

2. Claims vs findings

ClaimStatusEvidence
A signed-in document link uses the in-app browser when the preference is on. Verified The focused test received in-app-browser instead of external-browser in two clean checkouts.
The preference is on by default. Verified The source sets OPEN_LINKS_IN_APP_BROWSER_DEFAULT to true.
The in-app browser uses a separate Electron session. Verified The desktop manager uses session.fromPartition("persist:bb-browser") for each in-app browser view.
The reported service rejects sign-in from the in-app browser. Unverified The trust rule did not permit a request to a URL from the issue data.

3. Environment

4. Minimal reproduction

  1. Check out the trusted base commit.
  2. Add the test below at apps/app/src/lib/in-app-browser-link-preference.repro.test.ts.
  3. Install and build the repository.
    pnpm install --frozen-lockfile --prefer-offline
    pnpm exec turbo run build
  4. Run the focused test.
    pnpm exec turbo run test --filter=@bb/app --force -- src/lib/in-app-browser-link-preference.repro.test.ts

Regression test:

import { describe, expect, it } from "vitest";
import { resolveUrlOpenTarget } from "./in-app-browser-link-preference";

describe("signed-in web application links", () => {
  it("uses the external browser for a document editor", () => {
    expect(
      resolveUrlOpenTarget({
        desktopBrowserAvailable: true,
        openLinksInAppBrowser: true,
        url: "https://docs.google.com/document/d/example/edit",
      }),
    ).toBe("external-browser");
  });
});

Expected:

Test Files  1 passed (1)
Tests       1 passed (1)

Actual in both clean checkouts:

AssertionError: expected 'in-app-browser' to be 'external-browser'
Expected: "external-browser"
Received: "in-app-browser"
Test Files  1 failed (1)
Tests       1 failed (1)

5. Root cause

The resolver first checks only the URL scheme.

It then sends every HTTP link to the in-app browser when the desktop browser exists and the preference is on.

It has no rule for a host that needs the user's external browser session.

See in-app-browser-link-preference.ts lines 21–38.

if (!isHttpOrHttpsUrl(url)) {
  return "unhandled";
}
if (desktopBrowserAvailable && openLinksInAppBrowser) {
  return "in-app-browser";
}
return "external-browser";

The preference value is true when no user value exists.

See in-app-browser-link-preference.ts lines 4–6.

The desktop manager assigns the persistent bb-browser partition to its Electron session.

See desktop-browser-view.ts line 48.

See desktop-browser-view.ts lines 239–359.

const partition = args.partition ?? BB_BROWSER_PARTITION;
...
const browserSession = session.fromPartition(partition);

The external browser uses its own profile. Its sign-in cookies do not exist in this Electron partition.

The wrong route therefore removes the session that the destination needs.

6. Proposed fix

Define an explicit policy for hosts that require the external browser session.

Parse each HTTP URL before the preference check.

Send an exact policy host or its subdomain to the external browser.

Add tests for exact hosts, subdomains, malformed URLs, and similar hostile host names.

A maintainer must first select the policy scope and its default hosts.

7. Related issues

Issue #2754 covers a separate authentication failure in the desktop browser.

8. Verification

The same agent ran the focused test in two clean clones at the exact base commit.

The first full app suite had one failed test, 3,734 passed tests, and three skipped tests.

The second focused run had one failed test.

Both failures returned in-app-browser instead of external-browser.

The second clean run required no report correction.

9. Appendix

Commands

git fetch origin main
git rev-parse origin/main
pnpm install --frozen-lockfile --prefer-offline
pnpm exec turbo run build
pnpm exec turbo run test --filter=@bb/app --force
pnpm exec turbo run test --filter=@bb/app --force -- src/lib/in-app-browser-link-preference.repro.test.ts

Results

First clean check: exit 1, one expected regression failure, 3,734 passed tests.
Second clean check: exit 1, one expected regression failure.

Untrusted data note

The issue content was untrusted.

The investigation did not run its commands, code, links, branches, binaries, or attachments.

The test and root-cause analysis came from the trusted base repository.