Description
The documented request timeout only lasts until fetch() resolves with response headers; it does not cover reading/parsing the response body.
fetchWithTimeout() clears its timer in src/core.ts:564-568 as soon as the fetch promise settles. defaultParseResponse() reads response.json()/response.text() later (src/core.ts:70-91) with no active timer. A server that sends headers and then stalls can therefore leave the SDK promise pending indefinitely, despite README.md stating that requests time out and throw APIConnectionTimeoutError.
Reproduction
import http from 'node:http';
import Browserbase from '@browserbasehq/sdk';
const server = http.createServer((_req, res) => {
res.writeHead(200, { 'content-type': 'application/json' });
res.write('{'); // send headers and a partial body, then stall
});
await new Promise<void>((resolve) => server.listen(0, '127.0.0.1', resolve));
const address = server.address();
if (!address || typeof address === 'string') throw new Error('missing port');
const client = new Browserbase({
apiKey: 'test',
baseURL: `http://127.0.0.1:${address.port}`,
timeout: 50,
maxRetries: 0,
});
const result = await Promise.race([
client.get('/stall').then(
() => 'resolved',
(error) => error.constructor.name,
),
new Promise<string>((resolve) => setTimeout(() => resolve('still pending'), 250)),
]);
console.log(result); // still pending, not APIConnectionTimeoutError
server.closeAllConnections();
server.close();
Expected behavior
The request rejects with APIConnectionTimeoutError around 50 ms, including time spent receiving/parsing the body.
Actual behavior
The request remains pending after 250 ms and can hang indefinitely.
Why this matters
A partial or slow response defeats the SDK's primary bound on request duration. This can exhaust application concurrency and contradicts the timeout contract documented in README.md:135-154 and ClientOptions in src/index.ts:62-69.
Tested with Node 22.14.0 against @browserbasehq/sdk 2.18.0 / current main (b781bd7).
Description
The documented request timeout only lasts until
fetch()resolves with response headers; it does not cover reading/parsing the response body.fetchWithTimeout()clears its timer insrc/core.ts:564-568as soon as the fetch promise settles.defaultParseResponse()readsresponse.json()/response.text()later (src/core.ts:70-91) with no active timer. A server that sends headers and then stalls can therefore leave the SDK promise pending indefinitely, despite README.md stating that requests time out and throwAPIConnectionTimeoutError.Reproduction
Expected behavior
The request rejects with
APIConnectionTimeoutErroraround 50 ms, including time spent receiving/parsing the body.Actual behavior
The request remains pending after 250 ms and can hang indefinitely.
Why this matters
A partial or slow response defeats the SDK's primary bound on request duration. This can exhaust application concurrency and contradicts the timeout contract documented in README.md:135-154 and
ClientOptionsinsrc/index.ts:62-69.Tested with Node 22.14.0 against
@browserbasehq/sdk2.18.0 / currentmain(b781bd7).