Automattic/mongoose · error · TypeError

Cannot set both `validateAllPaths` and `pathsToSkip`

Error message

Cannot set both `validateAllPaths` and `pathsToSkip`

What it means

TypeError from Document#validate(): the options object combined `validateAllPaths: true` with `pathsToSkip`. `validateAllPaths` means 'validate every path in the schema', so asking it to also skip paths is contradictory and rejected before validation starts.

Source

Thrown at lib/document.js:2805

    const hasValidateModifiedOnlyOption = options &&
        (typeof options === 'object') &&
        ('validateModifiedOnly' in options);

    const pathsToSkip = options?.pathsToSkip || null;

    let shouldValidateModifiedOnly;
    if (hasValidateModifiedOnlyOption) {
      shouldValidateModifiedOnly = !!options.validateModifiedOnly;
    } else {
      shouldValidateModifiedOnly = this.$__schema.options.validateModifiedOnly;
    }
    this.$__.validateModifiedOnly = shouldValidateModifiedOnly;

    const validateAllPaths = options?.validateAllPaths;
    if (validateAllPaths) {
      if (pathsToSkip) {
        throw new TypeError('Cannot set both `validateAllPaths` and `pathsToSkip`');
      }
      if (pathsToValidate) {
        throw new TypeError('Cannot set both `validateAllPaths` and `pathsToValidate`');
      }
      if (hasValidateModifiedOnlyOption && shouldValidateModifiedOnly) {
        throw new TypeError('Cannot set both `validateAllPaths` and `validateModifiedOnly`');
      }
    }

    const _this = this;

    // only validate required fields when necessary
    let paths;
    let doValidateOptionsByPath;
    if (validateAllPaths) {
      paths = new Set(Object.keys(this.$__schema.paths));
      // gh-661: if a whole array is modified, make sure to run validation on all
      // the children as well

View on GitHub (pinned to 49cdab0136)

Solutions

  1. Remove `pathsToSkip` when using validateAllPaths
  2. Or drop validateAllPaths and keep pathsToSkip to validate everything except a few paths
  3. Audit shared/spread options objects so only one scoping mechanism survives

Example fix

// before
await doc.validate({ validateAllPaths: true, pathsToSkip: ['name'] });

// after
await doc.validate({ validateAllPaths: true });
// or the inverse: await doc.validate({ pathsToSkip: ['name'] });
Defensive patterns

Strategy: validation

Validate before calling

function assertValidateOptions(opts = {}) {
  if (opts.validateAllPaths && opts.pathsToSkip) {
    throw new TypeError('Choose either validateAllPaths or pathsToSkip, not both');
  }
}
assertValidateOptions(opts);
await doc.validate(opts);

Try / catch

try {
  await doc.validate(opts);
} catch (err) {
  if (err instanceof TypeError && err.message.includes('validateAllPaths')) {
    // options conflict; rebuild opts with exactly one scoping mechanism
  } else { throw err; }
}

Prevention

When it happens

Trigger: `doc.validate({ validateAllPaths: true, pathsToSkip: ['name'] })` or `pathsToSkip: 'name email'` (string form) in the same options object.

Common situations: Refactoring validation options incrementally and leaving both knobs set; spreading a shared defaults object that already contains pathsToSkip into a call that adds validateAllPaths.

Related errors


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