You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
MockPool/MockClient cleanMocks() doesn't clear the interceptors that Node.js global fetch uses #6013
After mockPool.cleanMocks(), requests from Node.js' global fetch still match the interceptors from before the call, and never match interceptors added after it. Requests through undici's own fetch/request aren't affected.
Cause: since #5648 (v8.10.1), MockAgent.dispatch mirrors a pool's interceptors into a separate ${origin}#http1-only dispatcher for legacy global dispatcher consumers like Node.js' bundled fetch (which goes through Dispatcher1Wrapper with allowH2: false). It does so by sharing the kDispatches array once:
cleanMocks() on MockPool and MockClient replaces that array instead of emptying it:
cleanMocks(){this[kDispatches]=[]}
So the #http1-only dispatcher keeps the old array: its interceptors stay active, and new ones never reach it.
Reproduction
Standalone reproduction script:
'use strict'const{ test }=require('node:test')constassert=require('node:assert')const{ MockAgent, setGlobalDispatcher }=require('undici')test('cleanMocks() also clears the interceptors that global fetch uses',async(t)=>{constagent=newMockAgent()agent.disableNetConnect()setGlobalDispatcher(agent)t.after(()=>agent.close())constmockPool=agent.get('https://example.com')mockPool.intercept({path: '/'}).reply(200,'first').persist()assert.strictEqual(await(awaitfetch('https://example.com/')).text(),'first')mockPool.cleanMocks()mockPool.intercept({path: '/'}).reply(200,'second').persist()assert.strictEqual(await(awaitfetch('https://example.com/')).text(),'second')})
Expected Behavior
The second fetch gets 'second': after cleanMocks(), only the interceptors added after it apply.
Actual Behavior
The second fetch gets 'first':
actual: 'first',
expected: 'second',
Without .persist(), the first interceptor is used up, and the second fetch fails with MockNotMatchedError instead.
Environment
OS: Linux
Node.js version: v24.15.0
undici version: 8.12.1 (current main), also 8.11.2
Additional context
This breaks the common test setup of one MockAgent as the global dispatcher with cleanMocks() between tests, for code that uses Node.js' global fetch. I'll open a PR that empties the array in place.
Activity