Where: setupRoutes in internal/server/routes.go; JSONValidationMiddleware in internal/server/middleware.go.
Every route is registered with r.Get and chi's middleware.GetHead is not used, so chi does not route HEAD to the GET handler. Three wrong answers follow:
HEAD on any route, the health check included, answers 405 with an empty body. Uptime monitors and link checkers that probe with HEAD mark the service down. (The image's own HEALTHCHECK uses curl -sf, a GET, so deploy health is unaffected.)
On the /api/v1 and /ip sub-routers JSONValidationMiddleware wraps chi's 405: the captured answer has no Content-Type and no body, so the middleware treats it as JSON, finds the body empty, keeps the 405 and writes {"status":"error","error":{"msg":"Internal server error","code":405}} (plus @meta). A POST /api/v1/stats is told the server failed.
GET /api/v1/nothing answers chi's default text/plain "404 page not found", while GET /api/v1/as/4200000000 answers a JSON 404 envelope; README describes the JSON envelope for the API's answers.
Severity: low.
Definition of done
HEAD is served for every GET route (chi middleware.GetHead or explicit handlers).
The JSON sub-routers have NotFound and MethodNotAllowed handlers that write the JSON envelope with "Not found" and "Method not allowed" and the right code; JSONValidationMiddleware no longer invents "Internal server error" for a 4xx with an empty body.
Tests, failing before the fix, through s.router: HEAD /api/v1/stats answers 200 (today 405); POST /api/v1/stats answers 405 with error.msg "Method not allowed" (today "Internal server error"); GET /api/v1/nothing answers a JSON 404 envelope (today text/plain).
make check passes.
Model: fable-5-1
Where: `setupRoutes` in `internal/server/routes.go`; `JSONValidationMiddleware` in `internal/server/middleware.go`.
Every route is registered with `r.Get` and chi's `middleware.GetHead` is not used, so chi does not route HEAD to the GET handler. Three wrong answers follow:
- `HEAD` on any route, the health check included, answers 405 with an empty body. Uptime monitors and link checkers that probe with HEAD mark the service down. (The image's own `HEALTHCHECK` uses `curl -sf`, a GET, so deploy health is unaffected.)
- On the `/api/v1` and `/ip` sub-routers `JSONValidationMiddleware` wraps chi's 405: the captured answer has no Content-Type and no body, so the middleware treats it as JSON, finds the body empty, keeps the 405 and writes `{"status":"error","error":{"msg":"Internal server error","code":405}}` (plus `@meta`). A `POST /api/v1/stats` is told the server failed.
- `GET /api/v1/nothing` answers chi's default `text/plain` "404 page not found", while `GET /api/v1/as/4200000000` answers a JSON 404 envelope; README describes the JSON envelope for the API's answers.
Severity: low.
## Definition of done
- HEAD is served for every GET route (chi `middleware.GetHead` or explicit handlers).
- The JSON sub-routers have `NotFound` and `MethodNotAllowed` handlers that write the JSON envelope with "Not found" and "Method not allowed" and the right code; `JSONValidationMiddleware` no longer invents "Internal server error" for a 4xx with an empty body.
- Tests, failing before the fix, through `s.router`: `HEAD /api/v1/stats` answers 200 (today 405); `POST /api/v1/stats` answers 405 with `error.msg` "Method not allowed" (today "Internal server error"); `GET /api/v1/nothing` answers a JSON 404 envelope (today text/plain).
- `make check` passes.
Model: fable-5-1
clawbot
self-assigned this 2026-10-19 22:35:19 +02:00
Built in #136: every route answers HEAD as it answers GET; the /api/v1 and /ip routes answer a path no route matches with a JSON 404 Not found and another method with a JSON 405 Method not allowed; JSONValidationMiddleware no longer says Internal server error for a 4xx sent without a body.
Model: opus-5-5
Built in https://git.eeqj.de/sneak/routewatch/pulls/136: every route answers `HEAD` as it answers `GET`; the `/api/v1` and `/ip` routes answer a path no route matches with a JSON 404 `Not found` and another method with a JSON 405 `Method not allowed`; `JSONValidationMiddleware` no longer says `Internal server error` for a 4xx sent without a body.
Model: opus-5-5
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.
Where:
setupRoutesininternal/server/routes.go;JSONValidationMiddlewareininternal/server/middleware.go.Every route is registered with
r.Getand chi'smiddleware.GetHeadis not used, so chi does not route HEAD to the GET handler. Three wrong answers follow:HEADon any route, the health check included, answers 405 with an empty body. Uptime monitors and link checkers that probe with HEAD mark the service down. (The image's ownHEALTHCHECKusescurl -sf, a GET, so deploy health is unaffected.)/api/v1and/ipsub-routersJSONValidationMiddlewarewraps chi's 405: the captured answer has no Content-Type and no body, so the middleware treats it as JSON, finds the body empty, keeps the 405 and writes{"status":"error","error":{"msg":"Internal server error","code":405}}(plus@meta). APOST /api/v1/statsis told the server failed.GET /api/v1/nothinganswers chi's defaulttext/plain"404 page not found", whileGET /api/v1/as/4200000000answers a JSON 404 envelope; README describes the JSON envelope for the API's answers.Severity: low.
Definition of done
middleware.GetHeador explicit handlers).NotFoundandMethodNotAllowedhandlers that write the JSON envelope with "Not found" and "Method not allowed" and the right code;JSONValidationMiddlewareno longer invents "Internal server error" for a 4xx with an empty body.s.router:HEAD /api/v1/statsanswers 200 (today 405);POST /api/v1/statsanswers 405 witherror.msg"Method not allowed" (today "Internal server error");GET /api/v1/nothinganswers a JSON 404 envelope (today text/plain).make checkpasses.Model: fable-5-1
Built in #136: every route answers
HEADas it answersGET; the/api/v1and/iproutes answer a path no route matches with a JSON 404Not foundand another method with a JSON 405Method not allowed;JSONValidationMiddlewareno longer saysInternal server errorfor a 4xx sent without a body.Model: opus-5-5