Read an empty PORT as unset, so SERVER_PORT still moves the server and NaN never reaches Bun.serve - #340
Open
kevin9327 wants to merge 1 commit into
Open
Conversation
…d NaN never reaches Bun.serve CopilotKit#312 read the port as `process.env.PORT ?? process.env.SERVER_PORT ?? "3001"`. `??` fires only on undefined, and a variable a compose file declares but the host never set, or `PORT=` left in a `.env`, arrives as an empty string: SERVER_PORT was never consulted, the disagreement check (`PORT && SERVER_PORT && …`) never fired, and `Number.parseInt("")` handed `Bun.serve` a NaN, which it answers by binding an ephemeral port. The server came up somewhere nobody had asked for, and the script polling SERVER_PORT reported one that never started — the failure CopilotKit#312 set out to remove, back through the other name. `parseInt` also parses a prefix, so `PORT=30o1` started the server on port 30 without a word. The port is now read by `loadConfig` through the same `optional` every other setting uses, where empty means unset, refusing anything that is not a whole number in 1–65535 the way the handoff caps and AGENT_STALL_TIMEOUT_MS already refuse a typo. Tests cover the empty-string case that is the whole point, the disagreement, and the refusals under both names.
kevin9327
requested review from
MikeRyanDev,
davidmckayv,
guidovizoso and
tylerslaton
as code owners
September 2, 2026 22:09
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
9 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this changes
#312 let either
PORTorSERVER_PORTmove the server, and refused the two disagreeing. It read them asprocess.env.PORT ?? process.env.SERVER_PORT ?? "3001", and??only fires onundefined. An unset variable declared in a compose file, orPORT=left in a.envnext to aSERVER_PORTthat was set, arrives as""— the same thing #96 and #114 found for the computer'sPORTand timeouts — so:rawPortwas"",SERVER_PORTnever consulted;PORT && SERVER_PORT && …, so it never fired either;Number.parseInt("", 10)isNaN, andBun.serve({ port: NaN })does not throw: it binds an ephemeral port.So the server came up on a port nobody had asked for, and
scripts/start.sh, which pollsSERVER_PORT, reported a server that never started. That is the failure #312 set out to remove, back through the other name. Separately,parseIntparses a prefix:PORT=30o1started the server on port 30 without a word.The port now belongs to
loadConfiginserver/src/config.ts, read through the sameoptionalevery other setting uses (trimmed, empty means unset), refusing anything that is not a whole number in 1–65535 the way the handoff caps andAGENT_STALL_TIMEOUT_MSalready refuse a typo, and comparing the two names as numbers.index.tsreadsconfig.port..env.examplesays an empty value counts as unset.Where it runs
Boundary and audit
config.ts.Changelog
Unreleased.Proof
Before, with
main's expression andPORT="",SERVER_PORT="3005":After —
loadConfigtests, including the empty-string case (PORT: ""withSERVER_PORT: "3005"→ 3005, both empty → 3001), the disagreement, and refusal of30o1,three,0,65536,1.5,-1under both names:bun run format:check,bun run lint, andbun run typecheck(server) pass. The app typecheck fails on a clean clone untilbun installpicks upreact-use-measurefrom #317, which is unrelated to this change.