You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
A class extending Error inside a compilePackages dependency fails instanceof Error — Hono's onError never sees a ZodError #9940
A class defined inside a compilePackages dependency that extends the
built-in Error fails instanceof Error, even though its prototype chain
visibly contains Error. The same subclass written in application code works.
The practical effect is that every framework which routes errors with err instanceof Error silently drops these. In our case a Zod validation
failure inside a Hono handler returns an empty 500 with content-type: text/plain and never reaches app.onError — where Node returns a 400 with a
JSON problem body.
The chain contains Error and instanceof Error is still false, so the Error the compiled package closes over is not the Error the application's instanceof tests against.
How it surfaces
Hono dispatches to onError only for values it considers errors. Throwing
from a handler, same build:
A thrown ZodError behaves exactly like a thrown string. Under Node all six
reach onError.
Impact
Every request whose body or query fails validation becomes an opaque 500 with
an empty body and nothing logged — the error never reaches the handler that
would have logged it. From the client's side a typo in a request is
indistinguishable from a server fault, and from the server's side it is
invisible.
That is the whole public API surface of an app that validates with Zod. It cost
us an afternoon on a bid endpoint that was returning 500 for what turned out to
be a malformed clientRef.
Note
z.ZodError itself works — instanceof z.ZodError is true — so an application
that checks the specific class first still behaves. The failure is only for code
that generalises over Error, which is what frameworks do.
Fixed by #9946, landed on main via merge train #9959. The train merged as its own branch, so the close-keyword never fired — closing manually, verified on main.
Activity
proggeramlug commentedon Sep 7, 2026
Fixed by #9946, landed on
mainvia merge train #9959. The train merged as its own branch, so the close-keyword never fired — closing manually, verified on main.