Automattic/mongoose · error · MongooseError

Path "${this.path}" may not have `allowNull` specified when

Error message

Path "${this.path}" may not have `allowNull` specified when `required` is true

What it means

SchemaType.prototype.required() throws when a path is made required with a non-function value while an allowNull option (or a previously registered allowNull validator) is present. A non-function required value already rejects null, so allowNull alongside it is contradictory and Mongoose refuses the combination.

Source

Thrown at lib/schemaType.js:1175

  }

  if (required === false) {
    this.validators = this.validators.filter(function(v) {
      return v.validator !== this.requiredValidator;
    }, this);

    this.isRequired = false;
    delete this.originalRequiredValue;
    return this;
  }

  const _this = this;
  this.isRequired = true;
  this.originalRequiredValue = required;

  if (typeof this.originalRequiredValue !== 'function' &&
      (utils.hasUserDefinedProperty(this.options, 'allowNull') || this.allowNullValidator != null)) {
    throw new MongooseError('Path "' + this.path + '" may not have `allowNull` specified when `required` is true');
  }

  this.requiredValidator = function(v) {
    const cachedRequired = this?.$__?.cachedRequired;

    // no validation when this path wasn't selected in the query.
    if (cachedRequired != null && !this.$__isSelected(_this.path) && !this[documentIsModified](_this.path)) {
      return true;
    }

    // `$cachedRequired` gets set in `_getPathsToValidate()` so we
    // don't call required functions multiple times in one validate call
    // See gh-6801
    if (cachedRequired != null && _this.path in cachedRequired) {
      const res = cachedRequired[_this.path] ?
        _this.checkRequired(v, this) :
        true;
      delete cachedRequired[_this.path];

View on GitHub (pinned to 49cdab0136)

Solutions

  1. Remove allowNull from the field definition when required is true (required already rejects null)
  2. If null must sometimes pass, make required a function: required: function() { return this.status === 'active'; } (function required values skip this check)
  3. Drop the required flag and keep allowNull, enforcing presence with a custom validator

Example fix

// before
new Schema({ name: { type: String, required: true, allowNull: false } });
// after
new Schema({ name: { type: String, required: true } });
Defensive patterns

Strategy: validation

Validate before calling

function assertNoRequiredAllowNullConflict(def) {
  const req = def.required;
  const hasAllowNull = Object.prototype.hasOwnProperty.call(def, 'allowNull');
  if (req === true && hasAllowNull) throw new Error(`Path conflicts: required=true with allowNull`);
}
assertNoRequiredAllowNullConflict(fieldDef);

Type guard

function hasConflictingRequired(def) {
  return def.required === true &&
    (Object.prototype.hasOwnProperty.call(def, 'allowNull') || def.allowNull !== undefined);
}

Try / catch

try { new Schema(defs); } catch (err) { if (/may not have `allowNull`/.test(err.message)) failFastWithSchemaHint(err); throw err; }

Prevention

When it happens

Trigger: Defining new Schema({ name: { type: String, required: true, allowNull: false } }); calling path.required(true) on a path where path.allowNull(false) was previously called; recompiling a schema that mixes required: true with a user-defined allowNull key in options.

Common situations: Turning an optional field into a required one and leaving allowNull: false behind; copying option blocks between fields during refactoring; generators that always emit allowNull.

Related errors


AI-assisted analysis of Automattic/mongoose@49cdab0136 (2026-08-21). Data as JSON: /api/errors/266be6e07b52c0b7. Report an issue: GitHub.