#4133·crawlee

BaseHttpClient.sendRequest() throws on any redirect that preserves the request body

Author: janbucharCreated Sep 16, 2026Updated Sep 16, 2026
Labelst-tooling
  • buildRedirectRequest() builds the next Request with a ReadableStream body but no duplex: 'half', which undici rejects outright
  • affects 307/308 with any body, and 301/302 on methods other than POST — every path through the else branch of the method's status logic; 302/303 on POST are fine because the body is dropped
  • sendRequest() rejects with a TypeError instead of returning a response, so callers see it as a client bug rather than a failed request
  • adding duplex: 'half' to that new Request(…) is enough; the clone is already sound, since initialRequest is cloned before the first send and its body is still undisturbed
javascript
import { createServer } from 'node:http';
import { FetchHttpClient } from '@crawlee/http-client';

const server = createServer((req, res) => {
    if (req.url === '/start') {
        res.writeHead(307, { location: '/end' });
        res.end();
        return;
    }
    req.resume();
    res.writeHead(200).end('ok');
});
await new Promise((resolve) => server.listen(0, resolve));
const base = `http://127.0.0.1:${server.address().port}`;

// TypeError: RequestInit: duplex option is required when sending a body.
await new FetchHttpClient().sendRequest(new Request(`${base}/start`, { method: 'POST', body: 'hello' }));

@crawlee/[email protected], Node 26.8.2.