fastify/fastify · critical · TypeError
FST_ERR_OPTIONS_NOT_OBJ
FST_ERR_OPTIONS_NOT_OBJ
Error message
Options must be an object
What it means
Thrown by processOptions (fastify.js:859-860) when the argument passed to the fastify() factory is truthy but not of type 'object'. The guard `options && typeof options !== 'object'` catches strings, numbers, booleans, and functions. (null and undefined pass through; arrays pass because typeof array === 'object', though they will fail downstream.) Fastify requires a plain options object describing logger, body limits, AJV config, etc.
Source
Thrown at fastify.js:860
this[kSupportedHTTPMethods].bodywith.delete(method)
this[kSupportedHTTPMethods].bodyless.add(method)
}
const _method = method.toLowerCase()
if (!this.hasDecorator(_method)) {
this.decorate(_method, function (url, options, handler) {
return router.prepareRoute.call(this, { method, url, options, handler })
})
}
return this
}
}
function processOptions (options, defaultRoute, onBadUrl, onMaxParamLength) {
// Options validations
if (options && typeof options !== 'object') {
throw new FST_ERR_OPTIONS_NOT_OBJ()
} else {
// Shallow copy options object to prevent mutations outside of this function
options = Object.assign({}, options)
}
if (
(options.querystringParser && typeof options.querystringParser !== 'function') ||
(
options.routerOptions?.querystringParser &&
typeof options.routerOptions.querystringParser !== 'function'
)
) {
throw new FST_ERR_QSP_NOT_FN(typeof (options.querystringParser ?? options.routerOptions.querystringParser))
}
if (options.schemaController && options.schemaController.bucket && typeof options.schemaController.bucket !== 'function') {
throw new FST_ERR_SCHEMA_CONTROLLER_BUCKET_OPT_NOT_FN(typeof options.schemaController.bucket)
}View on GitHub (pinned to 7299a57d3f)
Solutions
- Pass a plain object: `const app = fastify({ logger: true })`.
- If reading config from env, build the object explicitly: `fastify({ port: Number(process.env.PORT) })`.
- Pass nothing (fastify()) or null for defaults rather than a scalar.
Example fix
// before
const app = fastify(process.env.PORT) // PORT is a string
// after
const app = fastify({ port: Number(process.env.PORT) }) Defensive patterns
Strategy: type-guard
Validate before calling
function buildFastify(opts) {
if (opts != null && (typeof opts !== 'object' || Array.isArray(opts))) {
throw new TypeError('fastify() expects a plain options object, got ' + typeof opts)
}
return fastify(opts || {})
} Type guard
const isPlainOptions = (o) => o == null || (typeof o === 'object' && !Array.isArray(o))
Try / catch
try {
const app = fastify(maybeOpts)
} catch (err) {
if (err.code === 'FST_ERR_OPTIONS_NOT_OBJ') {
throw new TypeError('fastify() options must be a plain object, got ' + typeof maybeOpts)
}
throw err
} Prevention
- Always construct with an object literal: fastify({ logger: true }).
- Coerce env-derived config into an object before passing it to fastify().
When it happens
Trigger: Calling `fastify('3000')`, `fastify(3000)`, `fastify(true)`, or `fastify(() => {})` instead of `fastify({ port: 3000 })`.
Common situations: Confusing the factory with frameworks that accept a port string; passing a parsed CLI arg without coercing to an object; accidentally forwarding a config value instead of the config object.
Related errors
- FST_ERR_QSP_NOT_FN
- 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_SCHEMA_ERROR_FORMATTER_NOT_FN
AI-assisted analysis of fastify/fastify@7299a57d3f (2026-08-03).
Data as JSON: /data/errors/f60e79915aad9602.json.
Report an issue: GitHub.