Automattic/mongoose · error · MongooseError

Path "${this.path}" may not have `index` set to false and `s

Error message

Path "${this.path}" may not have `index` set to false and `sparse` set to true

What it means

Same options-processing check as the unique variant, but for sparse indexes: a path defined with `index: false` while an earlier option already registered an index object with `sparse: true` is rejected (lib/schemaType.js:106), because a sparse index is still an index mongoose would have to create.

Source

Thrown at lib/schemaType.js:106

      if (Array.isArray(this.options[prop])) {
        this.castFunction.apply(this, this.options[prop]);
      } else {
        this.castFunction(this.options[prop]);
      }
      continue;
    }
    if (utils.hasUserDefinedProperty(this.options, prop) && typeof this[prop] === 'function') {
      // { unique: true, index: true }
      if (prop === 'index' && this._index) {
        if (options.index === false) {
          const index = this._index;
          if (typeof index === 'object' && index != null) {
            if (index.unique) {
              throw new MongooseError('Path "' + this.path + '" may not have `index` ' +
                'set to false and `unique` set to true');
            }
            if (index.sparse) {
              throw new MongooseError('Path "' + this.path + '" may not have `index` ' +
                'set to false and `sparse` set to true');
            }
          }

          this._index = false;
        }
        continue;
      }

      const val = options[prop];
      // Special case so we don't screw up array defaults, see gh-5780
      if (prop === 'default') {
        this.default(val);
        continue;
      }

      const opts = Array.isArray(val) ? val : [val];

View on GitHub (pinned to 49cdab0136)

Solutions

  1. Remove `index: false` from the path
  2. Use `index: { sparse: true }` as the single declaration
  3. Control auto index creation with `autoIndex: false` at the connection/schema level instead of per-path

Example fix

// before
new Schema({ ref: { type: String, sparse: true, index: false } }); // throws

// after
new Schema({ ref: { type: String, index: { sparse: true } } });
Defensive patterns

Strategy: validation

Validate before calling

function assertIndexOptionsCompatible(def) {
  if (def.index === false && (def.unique === true || def.sparse === true || def.text === true)) {
    throw new Error('index:false cannot be combined with unique/sparse/text; use autoIndex:false instead');
  }
}

Type guard

const hasIndexOptionConflict = def => def?.index === false && Boolean(def?.unique || def?.sparse || def?.text);

Prevention

When it happens

Trigger: `new Schema({ ref: { type: String, sparse: true, index: false } })` — sparse registers an index object, then `index: false` contradicts it.

Common situations: Optional fields made sparse, combined with blanket per-path `index: false`; schema config merges between teams.

Related errors


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