Package: @adonisjs/assembler (seen on 7.8.2, still present in 8.5.2) with get-port 7.1.0
What happens
getPort() (used by the dev server and node ace test) calls:
getRandomPort({ port: Number(process.env.PORT) }) // no host
Without a host, get-port treats the port as taken if it is in use on undefined, 0.0.0.0 or any local interface address. So if port 3333 is bound on 127.1.1.63, node ace test configured with HOST=127.1.1.62 PORT=3333 is handed a random free PORT, even though 127.1.1.62:3333 is free.
The app then listens on 127.1.1.62:<random>. Anything that derives its URL from the configured port — typically a BASE_URL for supertest/@japa/api-client in functional tests — points at 127.1.1.62:3333 and every request fails with ECONNREFUSED.
Reproduce
- Alias a second loopback address (macOS:
sudo ifconfig lo0 alias 127.1.1.63).
- Occupy the port there:
node -e "require('net').createServer().listen(3333, '127.1.1.63')"
- In an Adonis app:
HOST=127.0.0.1 PORT=3333 NODE_DEBUG=adonisjs:core node ace test functional
- The debug line shows
listening to utils http server, host :127.0.0.1, port: <random>, although 127.0.0.1:3333 is free.
Why it matters
Running several checkouts' test suites side by side on one machine — each on its own loopback IP and the same port — is a natural way to parallelise. The run that starts last loses the race and fails every HTTP test, and nothing in the output says why.
Suggested fix
Pass the configured host through, so availability is checked where the server will actually bind:
getRandomPort({ port: Number(process.env.PORT), host: process.env.HOST })
(and the same for the .env-derived branch). When HOST is unset, behaviour stays as today.
Package:
@adonisjs/assembler(seen on 7.8.2, still present in 8.5.2) withget-port7.1.0What happens
getPort()(used by the dev server andnode ace test) calls:Without a
host,get-porttreats the port as taken if it is in use onundefined,0.0.0.0or any local interface address. So if port 3333 is bound on127.1.1.63,node ace testconfigured withHOST=127.1.1.62 PORT=3333is handed a random freePORT, even though127.1.1.62:3333is free.The app then listens on
127.1.1.62:<random>. Anything that derives its URL from the configured port — typically aBASE_URLforsupertest/@japa/api-clientin functional tests — points at127.1.1.62:3333and every request fails withECONNREFUSED.Reproduce
sudo ifconfig lo0 alias 127.1.1.63).node -e "require('net').createServer().listen(3333, '127.1.1.63')"HOST=127.0.0.1 PORT=3333 NODE_DEBUG=adonisjs:core node ace test functionallistening to utils http server, host :127.0.0.1, port: <random>, although127.0.0.1:3333is free.Why it matters
Running several checkouts' test suites side by side on one machine — each on its own loopback IP and the same port — is a natural way to parallelise. The run that starts last loses the race and fails every HTTP test, and nothing in the output says why.
Suggested fix
Pass the configured host through, so availability is checked where the server will actually bind:
(and the same for the
.env-derived branch). WhenHOSTis unset, behaviour stays as today.