{"record":{"id":"33103692e01fea5c","repo":"Automattic/mongoose","slug":"model-fnname-cannot-run-without-a-model-as-331036","errorCode":null,"errorMessage":"`Model.${fnName}()` cannot run without a model as `this`. Make sure you are not calling `new Model.${fnName}()`","messagePattern":"`Model\\.(.+?)\\(\\)` cannot run without a model as `this`\\. Make sure you are not calling `new Model\\.(.+?)\\(\\)`","errorType":"exception","errorClass":"MongooseError","httpStatus":null,"severity":"error","filePath":"lib/model.js","lineNumber":1070,"sourceCode":"  }\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}\n\n/**\n * This function is responsible for initializing the underlying connection in MongoDB based on schema options.\n * This function performs the following operations:","sourceCodeStart":1052,"sourceCodeEnd":1088,"githubUrl":"https://github.com/Automattic/mongoose/blob/49cdab01366679723b487ecb754b38570f783289/lib/model.js#L1052-L1088","documentation":"Second branch of `_checkContext`: the receiver is an object but lacks the internal `modelSymbol` property, which every real compiled mongoose Model carries. The canonical trigger is `new Model.someStatic()` — e.g. `new Model.discriminator()` — where `new` boxes the call on a fresh object without the symbol. The comment in the source says this check exists precisely because `new Model.discriminator()` otherwise produces an incomprehensible error.","triggerScenarios":"`const d = new Event.discriminator('Click', schema);`; `new User.init();`; any Model static invoked with `new` because the capitalized name reads like a class constructor; also calling a static with `.call(somePlainObject, ...)`.","commonSituations":"Copy-paste from code that uses classes with static factories; IDE autocompletion inserting `new` on capitalized methods; migrating from patterns like `new Model.findById()`. Note: only statics go through _checkContext — document methods (`new Model({...})`) are the legitimate constructor use.","solutions":["Remove `new`: `Event.discriminator('Click', schema)` returns the model directly","Keep `new` only for the actual constructor: `const doc = new Event({...})`","If wrapping statics, call them off the model: `MyModel.findOne(...)`"],"exampleFix":"// before\nconst Clicked = new Event.discriminator('Clicked', clickedSchema);\n\n// after\nconst Clicked = Event.discriminator('Clicked', clickedSchema);","handlingStrategy":"type-guard","validationCode":"// Guard in dev builds: model statics must never be invoked with `new`\nconst safeStatic = (Model, fnName, ...args) => {\n  if (!isMongooseModel(Model)) throw new TypeError('Pass the model, not an instance/plain object');\n  return Model[fnName](...args); // note: no `new` on statics\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}","tryCatchPattern":null,"preventionTips":["Reserve `new` for documents (`new Model({...})`); statics like discriminator/init/syncIndexes never take `new`","Prefer TypeScript: `new Model.init()` is a type error against the official mongoose types","During review, search for `new \\w+\\.(discriminator|init|syncIndexes|findOne)` as a smell pattern"],"tags":["mongoose","this-context","new-misuse","statics"],"backgroundTag":"invalid-this-context","analyzedSha":"49cdab01366679723b487ecb754b38570f783289","analyzedAt":"2026-08-21T22:54:00.882Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}