Automattic/mongoose · error · StrictModeError

Field `${key}` is not in schema and strict mode is set to th

Error message

Field `${key}` is not in schema and strict mode is set to throw.

What it means

StrictModeError from the multi-key branch of Document#$set: you are writing a key that has no path in the schema while the effective strict mode is 'throw'. It fires on writes - direct assignment, doc.set({...}), or the model constructor - and is distinct from strictRead, which governs reads from the database.

Source

Thrown at lib/document.js:1206

        if (constructing && valForKey === void 0 &&
            this.$get(pathName) !== void 0) {
          continue;
        }

        if (pathtype === 'adhocOrUndefined') {
          pathtype = getEmbeddedDiscriminatorPath(this, pathName, { typeOnly: true });
        }

        if (pathtype === 'real' || pathtype === 'virtual') {
          this.$set(pathName, valForKey, constructing, options);
        } else if (pathtype === 'nested' && valForKey instanceof Document) {
          this.$set(pathName,
            valForKey.toObject({ transform: false }), constructing, options);
        } else if (strict === 'throw') {
          if (pathtype === 'nested') {
            throw new ObjectExpectedError(key, valForKey);
          } else {
            throw new StrictModeError(key);
          }
        } else if (pathtype === 'nested' && valForKey == null) {
          this.$set(pathName, valForKey, constructing, options);
        }
      } else {
        this.$set(pathName, valForKey, constructing, options);
      }
    }

    // Ensure all properties are in correct order
    const orderedDoc = {};
    const orderedKeys = Object.keys(this.$__schema.tree);
    for (let i = 0, len = orderedKeys.length; i < len; ++i) {
      (key = orderedKeys[i]) &&
      (Object.hasOwn(this._doc, key)) &&
      (orderedDoc[key] = undefined);
    }
    this._doc = Object.assign(orderedDoc, this._doc);

View on GitHub (pinned to 49cdab0136)

Solutions

  1. Add the field to the schema if it is legitimate data
  2. Fix the writer: correct the typo or strip unknown keys from the payload
  3. Relax to `strict: true` (the default) if unknown keys should be silently dropped
  4. Sanitize input objects with a schema-derived whitelist before set()

Example fix

// before
doc.set({ nmae: 'typo' }); // strict: 'throw' -> StrictModeError on `nmae`

// after
doc.set({ name: 'correct' });
// or whitelist first:
const known = new Set(Object.keys(MyModel.schema.paths).concat(['_id']));
doc.set(Object.fromEntries(Object.entries(body).filter(([k]) => known.has(k))));
Defensive patterns

Strategy: validation

Validate before calling

// Whitelist payloads against schema paths before assignment
const schemaKeys = new Set(Object.keys(MyModel.schema.paths).concat(['_id']));
function sanitize(payload) {
  return Object.fromEntries(Object.entries(payload).filter(([k]) => schemaKeys.has(k)));
}
doc.set(sanitize(req.body));

Type guard

function isKnownKey(model, k) {
  return k === '_id' || model.schema.path(k) != null;
}

Try / catch

try {
  doc.set(req.body);
} catch (err) {
  if (err instanceof mongoose.Error.StrictModeError) {
    // req.body contains a key not in the schema; the message names it
  } else { throw err; }
}

Prevention

When it happens

Trigger: `doc.set('legacyField', 1)`, `doc.legacyField = 1`, or `new Model({ legacyField: 1 })` when the schema (or the per-call set option) resolves strict to 'throw' and the key resolves to no schema path and no embedded discriminator path.

Common situations: Typos in field names; clients forwarding extra payload keys into set(); code still writing fields removed during a schema refactor; adopting strict: 'throw' specifically to catch this drift.

Related errors


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