{"record":{"id":"3ca37e1eac7d9759","repo":"Automattic/mongoose","slug":"base-schematype-class-does-not-implement-a-cast","errorCode":null,"errorMessage":"Base SchemaType class does not implement a `cast()` function","messagePattern":"Base SchemaType class does not implement a `cast\\(\\)` function","errorType":"exception","errorClass":"MongooseError","httpStatus":null,"severity":"error","filePath":"lib/schemaType.js","lineNumber":379,"sourceCode":"  }\n  if (message != null) {\n    this._castErrorMessage = message;\n  }\n\n  return this._castFunction;\n};\n\n/**\n * The function that Mongoose calls to cast arbitrary values to this SchemaType.\n *\n * @param {object} value value to cast\n * @param {Document} doc document that triggers the casting\n * @param {boolean} init\n * @api public\n */\n\nSchemaType.prototype.cast = function cast() {\n  throw new MongooseError('Base SchemaType class does not implement a `cast()` function');\n};\n\n/**\n * Sets a default option for this schema type.\n *\n * #### Example:\n *\n *     // Make all strings be trimmed by default\n *     mongoose.SchemaTypes.String.set('trim', true);\n *\n * @param {string} option The name of the option you'd like to set (e.g. trim, lowercase, etc...)\n * @param {any} value The value of the option you'd like to set.\n * @return {void}\n * @static\n * @memberOf SchemaType\n * @function set\n * @api public\n */","sourceCodeStart":361,"sourceCodeEnd":397,"githubUrl":"https://github.com/Automattic/mongoose/blob/49cdab01366679723b487ecb754b38570f783289/lib/schemaType.js#L361-L397","documentation":"SchemaType.prototype.cast is an abstract stub that always throws (lib/schemaType.js:379). If you register a custom schematype class that extends mongoose.SchemaType without overriding `cast()`, the first assignment or query cast on that path calls the inherited stub and throws this MongooseError.","triggerScenarios":"`class MyType extends mongoose.SchemaType { constructor(key, options) { super(key, options, 'MyType'); } }` with no cast method; `new Schema({ x: { type: MyType } })`; then `doc.x = 1` or any query on `x`.","commonSituations":"Porting custom-type recipes from older mongoose versions; forgetting the cast override while implementing getters/setters first; accidentally using SchemaType itself as a type.","solutions":["Implement `cast(value, doc, init, prev, options)` in the subclass; return the coerced value or throw `new mongoose.Error.CastError('MyType', value, this.path)`","For a pass-through type, return the value unchanged","If you only need coercion of an existing type, use a custom caster (e.g. `mongoose.Schema.Types.String.cast(fn)`) instead of a subclass"],"exampleFix":"// before\nclass MyType extends mongoose.SchemaType {\n  constructor(key, options) { super(key, options, 'MyType'); }\n}\n// doc.x = 1 -> Base SchemaType class does not implement a `cast()` function\n\n// after\nclass MyType extends mongoose.SchemaType {\n  constructor(key, options) { super(key, options, 'MyType'); }\n  cast(value, doc, init, prev, options) {\n    if (typeof value !== 'number') {\n      throw new mongoose.Error.CastError('MyType', value, this.path);\n    }\n    return value;\n  }\n}","handlingStrategy":"type-guard","validationCode":"const assert = require('node:assert');\nfunction registerCustomType(Schema, MyType) {\n  assert.strictEqual(\n    MyType.prototype.cast === mongoose.SchemaType.prototype.cast,\n    false,\n    'custom schema types must override cast()'\n  );\n  Schema.Types.MyType = MyType;\n}","typeGuard":"const implementsCast = TypeClass => typeof TypeClass?.prototype?.cast === 'function' && TypeClass.prototype.cast !== mongoose.SchemaType.prototype.cast;","tryCatchPattern":null,"preventionTips":["Cover custom schematypes with a unit test that assigns and queries a value (exercises cast)","Throw CastError (not generic Error) from custom cast implementations for consistent handling"],"tags":["mongoose","schematype","custom-types","cast","subclassing"],"backgroundTag":"unimplemented-abstract-method","analyzedSha":"49cdab01366679723b487ecb754b38570f783289","analyzedAt":"2026-08-21T22:54:00.882Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}