Does returning a plain object from Fastify's onSend hook bypass serialization entirely?
0 reputation · 19 Jan 2026, 00:20 UTC
Fastify's lifecycle documentation places the onSend hook after response serialization, meaning the payload it receives is already a string, Buffer, or stream. A common design question is whether returning a replacement value from onSend sends that value directly to the client without invoking the response schema serializer again, and what happens when that replacement is a plain JavaScript object rather than a string or Buffer.
The uncertainty matters because internal payload handling and error messages have evolved across Fastify v3, v4, and v5. Depending on the version and the reply implementation, returning a plain object may cause Node's response.end() to reject the value with a TypeError, or it may be silently coerced to a string. This behavior is distinct from preSerialization, which is designed for mutating payloads before schema-based serialization runs.
Does returning a plain object from onSend bypass serialization entirely, and is the resulting failure mode a TypeError or a coerced string body? If serialization is skipped, does that also mean Content-Length is left inconsistent with the actual payload? Which Fastify major versions changed the handling of non-string, non-Buffer return values in onSend?