Thanks for the clear report and @madamov's question was exactly the right one.
This is a genuine bug, and I've reproduced it. When you run a console project with Studio's Run button, the app executes inside the Studio process itself. When you press Stop, the interpreter stops, but the TCP listener your app created isn't being closed. This means the port stays bound by Studio until you quit Studio entirely. That explains everything you saw:
- The first Run works, but the second can't get the port - it's still held by the previous run's listener inside Studio.
- Random ports (
Port = 0) work every time, because each run gets a fresh port from the OS.
- Quitting and relaunching Studio frees the port and it works again - exactly once.
- Calling
server.Stop() makes no difference, because pressing Stop ends execution without running your app's own shutdown code.
Launching the built app directly (Build, then run it from Finder or the terminal) won't hit this, since the app is its own process and the OS reclaims its ports when it exits.
A fix is on the tracker: sockets (TCPServer and friends) will release their ports and connections when a run stops. In the meantime, the workarounds are the ones you've found - relaunch Studio to free the port, or test against a built copy of the app.
https://feedback.objo.dev/bug/1662