{"id":"f60e79915aad9602","repo":"fastify/fastify","slug":"fst-err-options-not-obj","errorCode":"FST_ERR_OPTIONS_NOT_OBJ","errorMessage":"Options must be an object","messagePattern":"Options must be an object","errorType":"exception","errorClass":"TypeError","httpStatus":500,"severity":"critical","filePath":"fastify.js","lineNumber":860,"sourceCode":"      this[kSupportedHTTPMethods].bodywith.delete(method)\n      this[kSupportedHTTPMethods].bodyless.add(method)\n    }\n\n    const _method = method.toLowerCase()\n    if (!this.hasDecorator(_method)) {\n      this.decorate(_method, function (url, options, handler) {\n        return router.prepareRoute.call(this, { method, url, options, handler })\n      })\n    }\n\n    return this\n  }\n}\n\nfunction processOptions (options, defaultRoute, onBadUrl, onMaxParamLength) {\n  // Options validations\n  if (options && typeof options !== 'object') {\n    throw new FST_ERR_OPTIONS_NOT_OBJ()\n  } else {\n    // Shallow copy options object to prevent mutations outside of this function\n    options = Object.assign({}, options)\n  }\n\n  if (\n    (options.querystringParser && typeof options.querystringParser !== 'function') ||\n    (\n      options.routerOptions?.querystringParser &&\n      typeof options.routerOptions.querystringParser !== 'function'\n    )\n  ) {\n    throw new FST_ERR_QSP_NOT_FN(typeof (options.querystringParser ?? options.routerOptions.querystringParser))\n  }\n\n  if (options.schemaController && options.schemaController.bucket && typeof options.schemaController.bucket !== 'function') {\n    throw new FST_ERR_SCHEMA_CONTROLLER_BUCKET_OPT_NOT_FN(typeof options.schemaController.bucket)\n  }","sourceCodeStart":842,"sourceCodeEnd":878,"githubUrl":"https://github.com/fastify/fastify/blob/7299a57d3fdce7da49f2c6d19ba08dc673e53f22/fastify.js#L842-L878","documentation":"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.","triggerScenarios":"Calling `fastify('3000')`, `fastify(3000)`, `fastify(true)`, or `fastify(() => {})` instead of `fastify({ port: 3000 })`.","commonSituations":"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.","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."],"exampleFix":"// before\nconst app = fastify(process.env.PORT) // PORT is a string\n\n// after\nconst app = fastify({ port: Number(process.env.PORT) })","handlingStrategy":"type-guard","validationCode":"function buildFastify(opts) {\n  if (opts != null && (typeof opts !== 'object' || Array.isArray(opts))) {\n    throw new TypeError('fastify() expects a plain options object, got ' + typeof opts)\n  }\n  return fastify(opts || {})\n}","typeGuard":"const isPlainOptions = (o) => o == null || (typeof o === 'object' && !Array.isArray(o))","tryCatchPattern":"try {\n  const app = fastify(maybeOpts)\n} catch (err) {\n  if (err.code === 'FST_ERR_OPTIONS_NOT_OBJ') {\n    throw new TypeError('fastify() options must be a plain object, got ' + typeof maybeOpts)\n  }\n  throw err\n}","preventionTips":["Always construct with an object literal: fastify({ logger: true }).","Coerce env-derived config into an object before passing it to fastify()."],"tags":["configuration","startup","type-error","fastify"],"analyzedSha":"7299a57d3fdce7da49f2c6d19ba08dc673e53f22","analyzedAt":"2026-08-03T17:43:01.300Z","schemaVersion":2}