Repository navigation
inspector: Network.loadingFinished sent for a request the session never saw #66747
Description
Version
v26.5.0 (also reproduces on v24.16.0 and on main)
Platform
Darwin arm64 (macOS)
Subsystem
inspector
What steps will reproduce the bug?
Run with node --experimental-network-inspection repro.js:
'use strict';
const http = require('http');
const inspector = require('inspector/promises');
const { once } = require('events');
(async () => {
let held;
const server = http.createServer((req, res) => { held = res; });
server.listen(0, '127.0.0.1');
await once(server, 'listening');
// Session A sees the request start and the response headers.
const a = new inspector.Session();
a.connect();
await a.post('Network.enable');
const req = http.get(`http://127.0.0.1:${server.address().port}/`);
while (!held) await new Promise((r) => setImmediate(r));
held.writeHead(200);
held.flushHeaders();
const [res] = await once(req, 'response');
a.disconnect();
// Session B connects while the body is still pending.
const b = new inspector.Session();
b.connect();
const events = [];
for (const m of ['requestWillBeSent', 'responseReceived',
'loadingFinished', 'loadingFailed']) {
b.on(`Network.${m}`, ({ params }) => events.push(`${m}:${params.requestId}`));
}
await b.post('Network.enable');
res.resume();
held.end('body');
await once(res, 'end');
await new Promise((r) => setImmediate(r));
console.log(events);
b.disconnect();
server.close();
})();How often does it reproduce? Is there a required condition?
Always. A session has to disconnect while a request is in flight, and another session has to enable the Network domain before that request completes.
What is the expected behavior? Why is that the expected behavior?
[]. Session B was never sent Network.requestWillBeSent for this request, so it should not get a terminal event for it. Network.responseReceived and Network.dataReceived are already dropped in this case, because the new session's agent has no entry for the request.
What do you see instead?
[ 'loadingFinished:node-network-event-1' ]
Additional information
NetworkAgent::loadingFinished and NetworkAgent::loadingFailed call the frontend unconditionally. The lookup in requests_ only runs afterwards, for bookkeeping. The same thing happens if the session disconnects before the response headers arrive.
Gating these two events on requests_ would not be correct: RequestsBuffer::enforceBufferLimits evicts entries for requests that are still in flight, so the session would never see those requests finish. A possible fix is a per-session set of announced request ids. requestWillBeSent would add to it, Network.enable/Network.disable would clear it, and loadingFinished/loadingFailed would remove the id and skip the frontend call if it wasn't there. I have a patch along these lines and can open a PR if that approach sounds right.
Activity
inoway46 commentedon Oct 15, 2026
I reproduced this on Node.js v26.12.0. Since Node.js uses CDP, I also checked Chrome, which emits
loadingFinishedin this scenario too. DevTools ignores the unknown request ID, and I observed no Network panel issues.This seems closer to expected behavior than a bug. Do you have a real-world use case where this causes a problem?