denoland/deno · error · TypeError
Cannot read url: request closed
Error message
Cannot read url: request closed
What it means
InnerRequest.currentUrl() resolves the LAST entry of urlList (the URL after redirects) lazily via the urlList[currentIndex]() closure. If that underlying source is closed, the call throws and is converted to TypeError 'Cannot read url: request closed' (capital C, matching currentUrl()). Distinct from error 84 only in which accessor and list index is involved.
Source
Thrown at ext/fetch/23_request.js:177
clientRid: null,
blobUrlEntry,
url() {
if (this.urlListProcessed[0] === undefined) {
try {
this.urlListProcessed[0] = this.urlList[0]();
} catch {
throw new TypeError("cannot read url: request closed");
}
}
return this.urlListProcessed[0];
},
currentUrl() {
const currentIndex = this.urlList.length - 1;
if (this.urlListProcessed[currentIndex] === undefined) {
try {
this.urlListProcessed[currentIndex] = this.urlList[currentIndex]();
} catch {
throw new TypeError("Cannot read url: request closed");
}
}
return this.urlListProcessed[currentIndex];
},
};
}
/**
* https://fetch.spec.whatwg.org/#concept-request-clone
* @param {InnerRequest} request
* @param {boolean} skipBody
* @returns {InnerRequest}
*/
function cloneInnerRequest(request, skipBody = false) {
const headerList = ArrayPrototypeMap(
request.headerList,
(x) => [x[0], x[1]],
);View on GitHub (pinned to 89f33cbef2)
Solutions
- Materialize the current/final URL while the request resource is still open (right after fetch resolves)
- Snapshot response.url and other derived strings instead of re-deriving them later from the request
- Tie request processing to request.signal so work stops when the connection closes
Example fix
// before
const job = fetch('https://example.com/a') // redirects
.then((res) => ({ get url() { return res.url; /* late access may hit closed source */ } }));
// after
const job = fetch('https://example.com/a').then((res) => {
const url = res.url; // capture eagerly
return { url };
}); Defensive patterns
Strategy: try-catch
Validate before calling
const finalUrl = (() => {
try {
return response.url; // materialize final (post-redirect) URL now
} catch {
return null;
}
})(); Try / catch
try {
report(req.currentUrl()); // or response.url
} catch (err) {
if (err instanceof TypeError && err.message === 'Cannot read url: request closed') return; // source gone, skip
throw err;
} Prevention
- Capture response.url as a string the moment fetch resolves
- Do not re-derive final URLs from request objects later in async flows
- Bind analytics/reporting to the Response snapshot, not the live request
When it happens
Trigger: Calling request.currentUrl() (used internally after redirect chains) on an op-backed request whose resource closed before the currentUrl getter could cache urlListProcessed[currentIndex].
Common situations: Redirect handling or response URL reporting that runs after the originating connection/resource was reaped; deferred logging of final URLs for followed redirects.
Related errors
- Cannot read headers: request closed
- cannot read url: request closed
- Invalid header: length must be 2, but is ${header.length}
- Method is not valid
- Method is forbidden
AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16).
Data as JSON: /api/errors/c12435333278e771.
Report an issue: GitHub.