Skip to content

fix(hono-server): 405 + Allow for method mismatches instead of opaque 404#2687

Merged
os-zhuang merged 2 commits into
mainfrom
claude/meta-put-post-alias-ugfara
Jul 8, 2026
Merged

fix(hono-server): 405 + Allow for method mismatches instead of opaque 404#2687
os-zhuang merged 2 commits into
mainfrom
claude/meta-put-post-alias-ugfara

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

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 same notFound sink as a genuinely missing path, so a POST to 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

  • HonoHttpServer now records every (method, pattern) pair registered through its verb methods.
  • A new route-pattern helper re-matches a concrete request path against those patterns (Hono-style :param → one segment, * → the rest; trailing slash tolerant).
  • The notFound handler computes the allowed methods for the request path. If the path matches routes under other methods, it returns 405 Method Not Allowed with an accurate Allow header and a descriptive body. A path matching no route stays a 404.
  • Static/SPA catch-alls registered straight on the raw Hono app are not tracked, so they never emit a spurious 405.

Before / after

# Before
$ curl -i -X POST /api/v1/meta/view/my_view
HTTP/1.1 404 Not Found
{"error":"Not found"}

# After
$ curl -i -X POST /api/v1/meta/view/my_view
HTTP/1.1 405 Method Not Allowed
Allow: DELETE, GET, HEAD, PUT
{"error":"Method Not Allowed","code":"METHOD_NOT_ALLOWED",
 "message":"POST is not supported for /api/v1/meta/view/my_view. Allowed: DELETE, GET, HEAD, PUT.",
 "method":"POST","path":"/api/v1/meta/view/my_view","allowed":["DELETE","GET","HEAD","PUT"]}

Tests

  • route-pattern.test.ts — pattern compilation & matching (params, wildcard, trailing slash, metachar escaping).
  • notfound-405.test.tsallowedMethodsForPath unit coverage + end-to-end assertions driving the real server through app.fetch (405 + Allow on mismatch, correct method still routes, unknown path stays 404).
  • Full package suite green (56 tests); typecheck, build, and lint clean.

Notes

  • The malformed-URL case from the issue (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

… 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
@vercel

vercel Bot commented Jul 8, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
spec Ready Ready Preview, Comment Jul 8, 2026 10:48am

Request Review

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/plugin-hono-server.

4 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/permissions/authentication.mdx (via @objectstack/plugin-hono-server)
  • content/docs/plugins/index.mdx (via @objectstack/plugin-hono-server)
  • content/docs/plugins/packages.mdx (via @objectstack/plugin-hono-server)
  • content/docs/releases/implementation-status.mdx (via @objectstack/plugin-hono-server)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

@github-actions github-actions Bot added documentation Improvements or additions to documentation tooling labels Jul 8, 2026
@os-zhuang os-zhuang marked this pull request as ready for review July 8, 2026 10:51
@os-zhuang os-zhuang merged commit b1081b8 into main Jul 8, 2026
16 checks passed
@os-zhuang os-zhuang deleted the claude/meta-put-post-alias-ugfara branch July 8, 2026 10:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants