fix(hono-server): 405 + Allow for method mismatches instead of opaque 404#2687
Merged
Conversation
… opaque 404
Hono routes a method mismatch to the same `notFound` sink as a genuinely
missing path, so a POST to a PUT-only route (e.g. the metadata save endpoint
`PUT /api/v1/meta/:type/:name`) returned a bare `{ "error": "Not found" }`
404 with no hint that the path exists under another verb (#2684).
Track every `(method, pattern)` pair registered through `HonoHttpServer` and
re-match the request path in the `notFound` handler: when the path lines up
with routes under other methods, answer `405 Method Not Allowed` with an
accurate `Allow` header and a descriptive body so callers can self-correct.
A path that matches no registered route stays a 404.
This is framework-wide — every registered endpoint benefits (metadata save,
translations, data PATCH, …), not just the metadata surface. Static/SPA
catch-alls registered straight on the raw Hono app are intentionally not
tracked, so they never produce a spurious 405.
Adds a `route-pattern` helper (Hono-style `:param` / `*` matching) with unit
tests and an end-to-end test driving the real server through `app.fetch`.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N9qJ2N2d1c9oCR5GPfBDaM
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
📓 Docs Drift CheckThis PR changes 1 package(s): 4 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N9qJ2N2d1c9oCR5GPfBDaM
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 & why
Closes the discoverability friction reported in #2684.
The metadata save endpoint is registered as
PUT /api/v1/meta/:type/:name. Hono routes a method mismatch to the samenotFoundsink as a genuinely missing path, so aPOSTto that (correct) path returned a bare{ "error": "Not found" }404 — with no hint that the path exists under another verb. This is a framework-wide gap, not a metadata-specific one: it affects every non-GET route (translations save,PATCH /data/:object/:id,DELETE /meta/:type/:name, …).Rather than aliasing
POST → PUT(which muddies REST semantics and doubles the OpenAPI surface), this fixes the root cause: tell the caller the right method.Approach
HonoHttpServernow records every(method, pattern)pair registered through its verb methods.route-patternhelper re-matches a concrete request path against those patterns (Hono-style:param→ one segment,*→ the rest; trailing slash tolerant).notFoundhandler computes the allowed methods for the request path. If the path matches routes under other methods, it returns405 Method Not Allowedwith an accurateAllowheader and a descriptive body. A path matching no route stays a404.Before / after
Tests
route-pattern.test.ts— pattern compilation & matching (params, wildcard, trailing slash, metachar escaping).notfound-405.test.ts—allowedMethodsForPathunit coverage + end-to-end assertions driving the real server throughapp.fetch(405 +Allowon mismatch, correct method still routes, unknown path stays 404).Notes
POST /meta/view/?mode=draft, missing:name) does not match any registered pattern, so it correctly stays a 404 — it is not a method mismatch.🤖 Generated with Claude Code
https://claude.ai/code/session_01N9qJ2N2d1c9oCR5GPfBDaM
Generated by Claude Code