{"record":{"id":"80a0f96729d7cd43","repo":"Automattic/mongoose","slug":"model-fnname-cannot-run-without-a-model-as","errorCode":null,"errorMessage":"`Model.${fnName}()` cannot run without a model as `this`. Make sure you are calling `MyModel.${fnName}()` where `MyModel` is a Mongoose model.","messagePattern":"`Model\\.(.+?)\\(\\)` cannot run without a model as `this`\\. Make sure you are calling `MyModel\\.(.+?)\\(\\)` where `MyModel` is a Mongoose model\\.","errorType":"exception","errorClass":"MongooseError","httpStatus":null,"severity":"error","filePath":"lib/model.js","lineNumber":1066,"sourceCode":"      submodel.discriminators = submodel.discriminators || {};\n      submodel.discriminators[name] =\n        model.__subclass(model.db, schema, submodel.collection.name);\n    }\n  }\n\n  return d;\n};\n\n/**\n * Make sure `this` is a model\n * @api private\n */\n\nfunction _checkContext(ctx, fnName) {\n  // Check context, because it is easy to mistakenly type\n  // `new Model.discriminator()` and get an incomprehensible error\n  if (ctx == null || ctx === global) {\n    throw new MongooseError('`Model.' + fnName + '()` cannot run without a ' +\n      'model as `this`. Make sure you are calling `MyModel.' + fnName + '()` ' +\n      'where `MyModel` is a Mongoose model.');\n  } else if (ctx[modelSymbol] == null) {\n    throw new MongooseError('`Model.' + fnName + '()` cannot run without a ' +\n      'model as `this`. Make sure you are not calling ' +\n      '`new Model.' + fnName + '()`');\n  }\n}\n\n// Model (class) features\n\n/*!\n * Give the constructor the ability to emit events.\n */\n\nfor (const i in EventEmitter.prototype) {\n  Model[i] = EventEmitter.prototype[i];\n}","sourceCodeStart":1048,"sourceCodeEnd":1084,"githubUrl":"https://github.com/Automattic/mongoose/blob/49cdab01366679723b487ecb754b38570f783289/lib/model.js#L1048-L1084","documentation":"Model statics such as discriminator(), init(), syncIndexes() begin with `_checkContext(this, fnName)`, which throws this MongooseError when `this` is null, undefined, or the global object. It means the function was detached from its model — typically by destructuring the method off the model or passing the bare function reference where it is later invoked unbound. The model is a function (class), so its statics rely on a correct receiver.","triggerScenarios":"`const { syncIndexes } = User; syncIndexes();`; passing `User.init` directly as a callback (`server.on('start', User.init)`) so it is called with an undefined receiver; `Promise.all([Model.init, Model.ensureIndexes])` (missing invocation is fine, but `.map(Model.init)` is not); `const fn = Model.discriminator; fn('X', schema)`.","commonSituations":"Refactors that destructure model methods for brevity; passing statics as event handlers or to frameworks that rebind `this` (Mocha, Express middleware chains); code ported from plain-object service classes where destructuring is safe.","solutions":["Call the method on the model itself: `await User.syncIndexes()` instead of a destructured `syncIndexes()`","Wrap in an arrow function when passing as a callback: `server.on('start', () => User.init())`","Bind explicitly if you need a reference: `const init = User.init.bind(User)`","Search for destructuring of model statics (`const { X } = SomeModel`) in the file named in the stack trace"],"exampleFix":"// before\nconst { syncIndexes } = User;\nawait syncIndexes(); // throws: no model as `this`\n\n// after\nawait User.syncIndexes();","handlingStrategy":"type-guard","validationCode":"// Receiver sanity check before invoking a stored static\nconst callStatic = (maybeModel, fn, ...args) => {\n  if (!isMongooseModel(maybeModel)) {\n    throw new TypeError('Expected a compiled mongoose Model as receiver');\n  }\n  return maybeModel[fn](...args);\n};","typeGuard":"function isMongooseModel(v) {\n  return typeof v === 'function' &&\n    typeof v.modelName === 'string' &&\n    v.db != null &&\n    typeof v.findOne === 'function' &&\n    typeof v.discriminator === 'function';\n}","tryCatchPattern":null,"preventionTips":["Never destructure statics off a Model (`const { init } = User` is a bug waiting to happen)","When handing model statics to event emitters or frameworks, always wrap: `() => User.init()` or `.bind(User)`","Enable @typescript-eslint's unbound-method rule so detached methods are flagged at lint time"],"tags":["mongoose","this-context","unbound-function","statics"],"backgroundTag":"invalid-this-context","analyzedSha":"49cdab01366679723b487ecb754b38570f783289","analyzedAt":"2026-08-21T22:54:00.882Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}