fastify/fastify · critical · TypeError
FST_ERR_SCHEMA_ERROR_FORMATTER_NOT_FN
FST_ERR_SCHEMA_ERROR_FORMATTER_NOT_FN
Error message
schemaErrorFormatter option should be a non async function. Instead got '%s'.
What it means
Thrown by validateSchemaErrorFormatter (fastify.js:1004-1005), called both at construction (fastify.js:356) and from setSchemaErrorFormatter (fastify.js:735). It fires when `schemaErrorFormatter` is defined but `typeof schemaErrorFormatter !== 'function'`. The formatter must be a regular (non-async) function Fastify can call synchronously to turn validation errors into a single Error.
Source
Thrown at fastify.js:1005
}
// Most devs do not know what to do with this error.
// In the vast majority of cases, it's a network error and/or some
// config issue on the load balancer side.
this.log.trace({ err }, `client ${errorLabel}`)
// Copying standard node behavior
// https://github.com/nodejs/node/blob/6ca23d7846cb47e84fd344543e394e50938540be/lib/_http_server.js#L666
// If the socket is not writable, there is no reason to try to send data.
if (socket.writable) {
socket.write(`HTTP/1.1 ${errorCode} ${errorStatus}\r\nContent-Length: ${body.length}\r\nContent-Type: application/json\r\n\r\n${body}`)
}
socket.destroy(err)
}
function validateSchemaErrorFormatter (schemaErrorFormatter) {
if (typeof schemaErrorFormatter !== 'function') {
throw new FST_ERR_SCHEMA_ERROR_FORMATTER_NOT_FN(typeof schemaErrorFormatter)
} else if (schemaErrorFormatter.constructor.name === 'AsyncFunction') {
throw new FST_ERR_SCHEMA_ERROR_FORMATTER_NOT_FN('AsyncFunction')
}
}
/**
* These export configurations enable JS and TS developers
* to consume fastify in whatever way best suits their needs.
* Some examples of supported import syntax includes:
* - `const fastify = require('fastify')`
* - `const { fastify } = require('fastify')`
* - `import * as Fastify from 'fastify'`
* - `import { fastify, TSC_definition } from 'fastify'`
* - `import fastify from 'fastify'`
* - `import fastify, { TSC_definition } from 'fastify'`
*/
module.exports = fastify
module.exports.errorCodes = errorCodesView on GitHub (pinned to 7299a57d3f)
Solutions
- Pass a synchronous function: `fastify({ schemaErrorFormatter: (errors, dataVar) => new Error(...) })`.
- Omit the option to use the default formatter.
- If importing the formatter, verify the export name and that it resolves to a function.
Example fix
// before
const app = fastify({ schemaErrorFormatter: { format: myFormat } })
// after
const app = fastify({ schemaErrorFormatter: (errors) => new Error(errors.map(e => e.message).join(',')) }) Defensive patterns
Strategy: type-guard
Validate before calling
function validateFormatter(fn) {
if (typeof fn !== 'function') {
throw new TypeError('schemaErrorFormatter must be a function, got ' + typeof fn)
}
return fn
}
const app = fastify(opts.schemaErrorFormatter
? { schemaErrorFormatter: validateFormatter(opts.schemaErrorFormatter) }
: {}) Type guard
const isFormatter = (fn) => typeof fn === 'function' && fn.constructor.name !== 'AsyncFunction'
Try / catch
try {
app.setSchemaErrorFormatter(formatter)
} catch (err) {
if (err.code === 'FST_ERR_SCHEMA_ERROR_FORMATTER_NOT_FN') {
throw new TypeError('schemaErrorFormatter must be a non-async function, got ' + typeof formatter)
}
throw err
} Prevention
- Provide a synchronous function for schemaErrorFormatter.
- If importing the formatter, confirm the export resolves to a function before passing it.
When it happens
Trigger: Calling `fastify({ schemaErrorFormatter: {} })`, `{ schemaErrorFormatter: 'fmt' }`, or `fastify.setSchemaErrorFormatter(undefined)`. Also when the formatter is imported as undefined.
Common situations: Passing a configuration object describing a formatter rather than the function; misspelled import; copy-pasting a config snippet that referenced an unbound symbol.
Related errors
- FST_ERR_SCHEMA_CONTROLLER_BUCKET_OPT_NOT_FN
- FST_ERR_AJV_CUSTOM_OPTIONS_OPT_NOT_OBJ
- FST_ERR_AJV_CUSTOM_OPTIONS_OPT_NOT_ARR
- FST_ERR_OPTIONS_NOT_OBJ
- FST_ERR_QSP_NOT_FN
AI-assisted analysis of fastify/fastify@7299a57d3f (2026-08-03).
Data as JSON: /data/errors/f87fd1847dbf9f31.json.
Report an issue: GitHub.