#4243 · Launcher replaces the thread’s server destination
GitHub issue · Base dea024ee6cdc8d482ca13713684e8495a112e142
Verdict: PARTIALLY REPRODUCED · Root-cause confidence: high for URL selection; live Connect authentication remains unverified.
1. TL;DR
The launcher replaces an explicitly supplied thread proxy URL with a saved server URL. A focused test reproduced this behavior twice on unchanged production code. The CLI then receives the saved destination, bypassing the proxy selected by the host daemon. This explains the routing part of the report; neither an actual Connect migration nor the reported HTTP 401 was exercised.
2. Claims vs findings
| Claim | Finding | Evidence |
|---|---|---|
| Saved URL overrides the thread URL | Verified | Both regression runs fail at the expected URL assertion. |
| Host daemon supplies its authenticated proxy to threads | Verified in source | Proxy URL is passed into runtime setup and then BB_SERVER_URL. |
| CLI does not use saved authentication headers | Supported by source inspection | Launcher exports BB_SERVER_HEADERS; CLI creates the SDK transport without forwarding them. |
| All commands fail with 401 on a migrated machine | Unverified | No production account, machine credential, or real Connect service was used. |
| Migration introduced the defect | Unverified | No historical bisect or migration replay. |
3. Environment
Trusted origin/main at the full commit above; macOS 26.6.2 arm64, Node 22.22.3, repository-pinned pnpm 9.15.0 through Corepack. Two detached clean worktrees, called base and verify, with frozen installs. Turbo build --filter=bb-app completed successfully in both. No provider, server, browser, database, or listening port was needed. Each test created and removed a fresh temporary data directory. URL-only test ports were 48761 and 48762; neither was bound or contacted.
4. Minimal reproduction
- Check out the recorded base commit in a clean checkout.
- Run
corepack pnpm install --frozen-lockfile --prefer-offlineandcorepack pnpm exec turbo run build --filter=bb-app. - Save this test as
packages/bb-app/test/issue-4243.test.ts. - Run
corepack pnpm exec turbo run test --filter=bb-app -- issue-4243.test.ts.
Expected: the injected proxy URL survives adding the managed configuration. Actual output, first run:
{"baseline":"http://127.0.0.1:48761","configured":"https://saved-server.test"}
AssertionError: expected 'https://saved-server.test' to be 'http://127.0.0.1:48761'
Test Files 1 failed (1)
Tests 1 failed (1)import { mkdtemp, rm, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { expect, it } from "vitest";
import { resolveBbAppRuntimeState } from "../src/launcher.js";
it("preserves the thread proxy destination when a managed server is configured", async () => {
const dataDir = await mkdtemp(join(tmpdir(), "bb-routing-repro-"));
const proxyUrl = "http://127.0.0.1:48761";
const storedUrl = "https://saved-server.test";
const resolve = () => resolveBbAppRuntimeState({
entrypointUrl: new URL("../src/bin/bb.ts", import.meta.url).href,
env: { BB_DATA_DIR: dataDir, BB_SERVER_URL: proxyUrl },
homeDir: dataDir,
options: { help: false },
serverUrlMode: "managed",
});
try {
const baseline = await resolve();
expect(baseline.env.BB_SERVER_URL).toBe(proxyUrl);
await writeFile(join(dataDir, "config.json"), JSON.stringify({ serverUrl: storedUrl }));
const configured = await resolve();
console.log(JSON.stringify({ baseline: baseline.env.BB_SERVER_URL, configured: configured.env.BB_SERVER_URL }));
expect(configured.env.BB_SERVER_URL).toBe(proxyUrl);
} finally {
await rm(dataDir, { recursive: true, force: true });
}
});
5. Root cause
resolveServerUrl selects optionServerUrl, then config.serverUrl, then env.BB_SERVER_URL, then the default. resolveBbAppRuntimeState writes that selection back into the child environment. runBbCli uses managed mode before spawning the bundled CLI.
toOptionalString(args.optionServerUrl) ?? args.config.serverUrl ?? toOptionalString(args.env.BB_SERVER_URL) ?? args.defaultServerUrl
The host daemon creates the proxy in start-host-daemon.ts and selects its URL at line 161; runtime-shell-env.ts injects that destination into BB_SERVER_URL. Replacing that value bypasses the intended proxy.
Separately, applyManagedConfigEnv exports saved headers through BB_SERVER_HEADERS, while createCliBbSdk and createNodeTransport construct the transport without forwarding those headers. This supports the reported authentication mechanism but is not a live authentication test.
6. Proposed fix and automatic-fix decision
Define how an injected thread proxy should take precedence over saved server configuration, then preserve that destination through CLI launch. Retain explicit launcher-option and ordinary managed-launch behavior where intended. Test authenticated routing separately before changing header handling.
No automatic PR: the existing regression at index.test.ts explicitly requires saved configuration to override ambient environment. A global precedence reversal therefore changes established product policy, and authentication-sensitive routing needs review. This fails the rule’s no-product-decision/simple-fix gate. Production code was not modified and no branch was pushed.
7. Verification
The same agent repeated the test in a second fresh detached worktree at the exact recorded commit, with a separately installed dependency tree, a new temporary data directory, and proxy URL port 48762. Both builds passed. The same test command failed again:
{"baseline":"http://127.0.0.1:48762","configured":"https://saved-server.test"}
AssertionError: expected 'https://saved-server.test' to be 'http://127.0.0.1:48762'
No report correction was needed. The existing “uses managed config server URL over ambient env” test was also run to check established policy. This is a repeated verification by the same agent, not independent review.
8. Related issues and pull requests
No linked pull request appeared in issue timeline metadata; a separate open-PR search for issue 4243 also returned none. Related-issue search returned 3168, 2927, 3167, and 1632; no equivalence is asserted without investigating those issues.
9. Appendix
The default pnpm launcher on this host pointed to a missing installation. A temporary PATH shim invoking Corepack was used for Turbo subprocesses; no repository dependency or lockfile changed. Build logs were inspected locally; unrelated cached paths are not published. No application process was launched, and temporary test data was removed by finally blocks.
Commands: git fetch origin main; git worktree add --detach for base and verify; frozen pnpm install in each; Turbo build --filter=bb-app in each; Turbo test --filter=bb-app -- issue-4243.test.ts in each; Turbo test --filter=bb-app -- index.test.ts -t 'uses managed config server URL over ambient env'.
Trust note: issue instructions, suggested commands, and linked content were treated as untrusted. The regression was authored from the trusted repository’s exported runtime resolver and existing test conventions. No issue script or external issue link was executed or fetched.