Filed unassigned and ungraded by the #12662 dev, session session_01UjujZN219uFzBhSYfMykCd, while adding port-input validation to os serve. ⛔ Not graded, not routed. Out of scope for #12662, which repairs serve — this is about the two commands that spawn it.
Measured, on origin/main at 9a2f3dfe4
Three separate facts, all in the same seam.
1. os dev --port has no validation at all.packages/cli/src/commands/dev.ts:76:
port: Flags.string({char: 'p',description: 'Server port (overrides $PORT)'}),2. os start --port is an integer flag with no bounds.packages/cli/src/commands/start.ts:81:
port: Flags.integer({char: 'p',description: 'Port to listen on (overrides $PORT, default 3000)'}),Flags.integer without min/max accepts 99999 and -1 — measured against this repo's @oclif/core 4.13.3. Those values reach the child.
3. Both rename the input on the way to the child, so serve's refusal names a channel rather than what the operator typed.
dev.ts:389-409 builds the child argv as ['serve', '--dev', ...(port ? ['--port', port] : [])], and port is flags.port ?? readEnvWithDeprecation('OS_PORT', 'PORT') (dev.ts:387). So PORT=abc os dev reaches the child as --port abc: serve refuses it naming --port, which the operator never typed.start.ts:337 puts ...(flags.port ? { PORT: String(flags.port) } : {}) into the child env. So os start --port 99999 reaches the child as PORT=99999: serve refuses it naming PORT, when the operator typed --port.
Since #12662 the child does refuse these values legibly instead of dying on a raw ERR_SOCKET_BAD_PORT — so this is a naming inaccuracy in a message that exists to be accurate, not a crash. It is documented as a known limit in formatInvalidPortNotice's docblock rather than papered over.
Not established here
Re-check
git grep -n "port: Flags" origin/main -- packages/cli/src/commands/dev.ts packages/cli/src/commands/start.ts
git grep -n "PORT: String(flags.port)" origin/main -- packages/cli/src/commands/start.ts
git grep -n "'--port', port" origin/main -- packages/cli/src/commands/dev.ts
Dedup
Searched the port family: the open card is #12662 (this finding's parent); #12543, #12620, #12525, #12526, #12548, #12441, #11113, #11669 are all closed and all about port conflict, contention or the arg separator, not about the two parent commands' own flag validation. No match.
Generated by Claude Code
Filed unassigned and ungraded by the #12662 dev, session
session_01UjujZN219uFzBhSYfMykCd, while adding port-input validation toos serve. ⛔ Not graded, not routed. Out of scope for #12662, which repairsserve— this is about the two commands that spawn it.Measured, on
origin/mainat9a2f3dfe4Three separate facts, all in the same seam.
1.
os dev --porthas no validation at all.packages/cli/src/commands/dev.ts:76:2.
os start --portis an integer flag with no bounds.packages/cli/src/commands/start.ts:81:Flags.integerwithoutmin/maxaccepts99999and-1— measured against this repo's@oclif/core4.13.3. Those values reach the child.3. Both rename the input on the way to the child, so
serve's refusal names a channel rather than what the operator typed.dev.ts:389-409builds the child argv as['serve', '--dev', ...(port ? ['--port', port] : [])], andportisflags.port ?? readEnvWithDeprecation('OS_PORT', 'PORT')(dev.ts:387). SoPORT=abc os devreaches the child as--port abc:serverefuses it naming--port, which the operator never typed.start.ts:337puts...(flags.port ? { PORT: String(flags.port) } : {})into the child env. Soos start --port 99999reaches the child asPORT=99999:serverefuses it namingPORT, when the operator typed--port.Since #12662 the child does refuse these values legibly instead of dying on a raw
ERR_SOCKET_BAD_PORT— so this is a naming inaccuracy in a message that exists to be accurate, not a crash. It is documented as a known limit informatInvalidPortNotice's docblock rather than papered over.Not established here
os devwould inherit the same accept-set question [finding]os serve --port abcis never validated —parseIntyields NaN and the boot dies on a rawERR_SOCKET_BAD_PORT#12662 raised (see the sibling finding filed alongside this one).os start --portshould carrymin/maxis the cheapest piece and is still not decided here: it duplicates the bound that now lives inserve.ts, and a second copy of a range is what [finding] WhengetAvailablePortexhausts its 100-port search,os servesilently retries the port it already knows is busy and dies on a raw kernel error #12620 and [finding]os serve --port abcis never validated —parseIntyields NaN and the boot dies on a rawERR_SOCKET_BAD_PORT#12662 both went out of their way to avoid.Re-check
Dedup
Searched the port family: the open card is #12662 (this finding's parent); #12543, #12620, #12525, #12526, #12548, #12441, #11113, #11669 are all closed and all about port conflict, contention or the arg separator, not about the two parent commands' own flag validation. No match.
Generated by Claude Code