fix(sandbox): cancel CDP probe response bodies (#109767)

* fix(sandbox): cancel unsuccessful CDP probe responses

Release unread response bodies when sandbox CDP startup probes receive
non-success statuses so retry loops do not retain transport resources.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(sandbox): cancel all CDP probe responses

* test(sandbox): simplify CDP probe cleanup coverage

Signed-off-by: sallyom <somalley@redhat.com>

---------

Signed-off-by: sallyom <somalley@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: sallyom <somalley@redhat.com>
This commit is contained in:
Wynne668
2026-07-19 23:12:27 -04:00
committed by GitHub
co-authored by Cursor sallyom
parent 7d4dccf959
commit cacd98304e
2 changed files with 41 additions and 0 deletions
+40
View File
@@ -774,6 +774,46 @@ describe("ensureSandboxBrowser create args", () => {
);
});
it.each([200, 503])(
"cancels the CDP probe response body after a %i startup probe",
async (status) => {
const cancels: Array<ReturnType<typeof vi.fn>> = [];
vi.spyOn(globalThis, "fetch").mockImplementation(async () => {
const cancel = vi.fn().mockResolvedValue(undefined);
cancels.push(cancel);
return {
ok: status === 200,
body: { cancel },
} as never;
});
bridgeMocks.startBrowserBridgeServer.mockImplementationOnce(async (params) => {
await params.onEnsureAttachTarget?.({});
throw new Error("probe completed before bridge creation");
});
const cfg = buildConfig(false);
cfg.browser.autoStartTimeoutMs = 50;
await expect(
ensureTestSandboxBrowser({
scopeKey: "session:test",
workspaceDir: "/tmp/workspace",
agentWorkspaceDir: "/tmp/workspace",
cfg,
}),
).rejects.toThrow(
status === 200
? "probe completed before bridge creation"
: "hung container has been forcefully removed",
);
expect(cancels).not.toHaveLength(0);
for (const cancel of cancels) {
expect(cancel).toHaveBeenCalledOnce();
}
},
);
it("keeps a stalled CDP request inside the browser startup deadline", async () => {
const sockets = new Set<Socket>();
let requestPath: string | undefined;
+1
View File
@@ -99,6 +99,7 @@ async function waitForSandboxCdp(params: {
headers: { Authorization: buildSandboxCdpAuthHeader(params.authToken) },
signal: ctrl.signal,
});
await res.body?.cancel().catch(() => undefined);
if (res.ok) {
return true;
}