Until recently, my team was using Node.js v18.13.0. Our CI system picked up Node.js v18.17.0 and started failing. Specifically, we started failing when using Chai to perform expect(…).to.deep.equal on URLs.
After reading the changelog for v18.17.0, I see that Ada-based URLs were backported to Node.js 18 (see here).
Narrowing down some more, it seems there is a behavior change in Node.js 18.17.0 where Symbol(query) is lazily set on URLs whenever searchParams is accessed (see here). So, if you've never accessed that property of a URL, Symbol(query) does not exist; however, once you have accessed that property, Symbol(query) does exist. This leads to the following breakage (I'm demonstrating with Mocha):
const { expect } = require('chai')
describe('URL', () => {
it('succeeds', () => {
const url = new URL('foo://bar')
expect(url).to.deep.equal(new URL('foo://bar'))
})
// The following succeeded in Node.js < v18.17.0.
it('fails', () => {
const url = new URL('foo://bar')
void url.searchParams
expect(url).to.deep.equal(new URL('foo://bar'))
})
})
Maybe this is working as expected, but it was an unfortunate bug we hit. We have worked around it by changing our tests to no longer expect(…).to.deep.equal on URLs.
Until recently, my team was using Node.js v18.13.0. Our CI system picked up Node.js v18.17.0 and started failing. Specifically, we started failing when using Chai to perform
expect(…).to.deep.equalon URLs.After reading the changelog for v18.17.0, I see that Ada-based URLs were backported to Node.js 18 (see here).
Narrowing down some more, it seems there is a behavior change in Node.js 18.17.0 where
Symbol(query)is lazily set on URLs wheneversearchParamsis accessed (see here). So, if you've never accessed that property of a URL,Symbol(query)does not exist; however, once you have accessed that property,Symbol(query)does exist. This leads to the following breakage (I'm demonstrating with Mocha):Maybe this is working as expected, but it was an unfortunate bug we hit. We have worked around it by changing our tests to no longer
expect(…).to.deep.equalon URLs.