Start a second instance while the port is bound and the process does not exit. Observed, then it sat there for 183 s:
{"level":"INFO","msg":"http begin listen","listenaddr":":18080"}
{"level":"ERROR","msg":"listen error","error":"listen tcp :18080: bind: address already in use"}
[Fx] RUNNING
Cause: Server's fx OnStart hook returns nil immediately and runs s.Run() in a goroutine (internal/server/server.go:104-116). The listen error only calls s.cancelFunc() (internal/server/http.go:43-50), which ends serve()'s wait but never invokes fx.Shutdowner, so the process stays alive with no listener.
Operational impact: systemd Restart=on-failure and Docker restart policies never fire. The service is down and looks up. It is also the precondition for the duplicate-delivery defect filed alongside this one.
Definition of done:
a listen failure calls fx.Shutdowner.Shutdown() (or equivalent) so the process exits non-zero
PORT bound by another process: a second start exits non-zero within a second or so, and logs the bind error
a regression test asserts the process terminates on listen failure rather than reporting RUNNING
no change to the clean-shutdown path: docker stop still drains within the existing grace window
Start a second instance while the port is bound and the process does not exit. Observed, then it sat there for 183 s:
```
{"level":"INFO","msg":"http begin listen","listenaddr":":18080"}
{"level":"ERROR","msg":"listen error","error":"listen tcp :18080: bind: address already in use"}
[Fx] RUNNING
```
Cause: `Server`'s fx `OnStart` hook returns `nil` immediately and runs `s.Run()` in a goroutine (`internal/server/server.go:104-116`). The listen error only calls `s.cancelFunc()` (`internal/server/http.go:43-50`), which ends `serve()`'s wait but never invokes `fx.Shutdowner`, so the process stays alive with no listener.
Operational impact: systemd `Restart=on-failure` and Docker restart policies never fire. The service is down and looks up. It is also the precondition for the duplicate-delivery defect filed alongside this one.
Definition of done:
- a listen failure calls `fx.Shutdowner.Shutdown()` (or equivalent) so the process exits non-zero
- `PORT` bound by another process: a second start exits non-zero within a second or so, and logs the bind error
- a regression test asserts the process terminates on listen failure rather than reporting RUNNING
- no change to the clean-shutdown path: `docker stop` still drains within the existing grace window
clawbot
added this to the 1.0.0 milestone 2026-08-20 05:46:55 +02:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Start a second instance while the port is bound and the process does not exit. Observed, then it sat there for 183 s:
Cause:
Server's fxOnStarthook returnsnilimmediately and runss.Run()in a goroutine (internal/server/server.go:104-116). The listen error only callss.cancelFunc()(internal/server/http.go:43-50), which endsserve()'s wait but never invokesfx.Shutdowner, so the process stays alive with no listener.Operational impact: systemd
Restart=on-failureand Docker restart policies never fire. The service is down and looks up. It is also the precondition for the duplicate-delivery defect filed alongside this one.Definition of done:
fx.Shutdowner.Shutdown()(or equivalent) so the process exits non-zeroPORTbound by another process: a second start exits non-zero within a second or so, and logs the bind errordocker stopstill drains within the existing grace windowclawbot referenced this issue2026-08-20 05:56:52 +02:00