compileSerializationSchema reuses the first serializer when metadata changes
Description
reply.compileSerializationSchema() forwards httpStatus and contentType to a custom serializer compiler, but its cache is keyed only by the schema object. Reusing the same schema object with different metadata therefore returns the serializer compiled for the first call.
This is present on main at 1beaf7e72d24b2fc63a02a7f5806772a00e45454:
compileSerializationSchemachecks and stores by schema identity only- The documentation says both optional values are forwarded to a custom compiler
Reproduction
const Fastify = require('fastify')
const app = Fastify()
const compiled = []
app.setSerializerCompiler(({ httpStatus, contentType }) => {
compiled.push({ httpStatus, contentType })
return (data) => JSON.stringify({ httpStatus, contentType, data })
})
app.get('/', (_request, reply) => {
const schema = { type: 'object' }
const first = reply.compileSerializationSchema(schema, '200', 'application/json')
const second = reply.compileSerializationSchema(schema, '201', 'application/vnd.example+json')
return {
sameFunction: first === second,
compiled,
first: first({ value: 1 }),
second: second({ value: 2 }),
}
})
app.inject({ method: 'GET', url: '/' }).then(({ payload }) => console.log(payload))Actual behavior
The compiler is invoked once, sameFunction is true, and both calls use the 200 / application/json metadata captured by the first serializer.
Expected behavior
Changing httpStatus or contentType should produce (or retrieve) a serializer compiled for that metadata tuple.
Possible direction
Keep the weak schema identity cache, but store serializers below it by httpStatus and contentType, including a stable representation for omitted values.
I found this while benchmarking an automated code-review workflow and manually verified the source path and reproduction before reporting it.
Source: fastify/fastify