Automattic/mongoose · error · StrictModeError
Field `${path}` is not in schema and strictRead is set to th
Error message
Field `${path}` is not in schema and strictRead is set to throw. What it means
StrictModeError thrown while Mongoose hydrates a document (init from a query result or Model.hydrate()). The stored object contains a field that has no matching path in the schema, and `strictRead` is set to 'throw'. `strictRead` only governs reads: by default unknown DB fields are kept on the hydrated document; `strictRead: true` filters them out and 'throw' raises this error instead.
Source
Thrown at lib/document.js:788
for (let index = 0; index < len; ++index) {
i = keys[index];
// avoid prototype pollution
if (specialProperties.has(i)) {
continue;
}
path = prefix ? prefix + i : i;
schemaType = docSchema.path(path);
// Should still work if not a model-level discriminator, but should not be
// necessary. This is *only* to catch the case where we queried using the
// base model and the discriminated model has a projection
if (docSchema.$isRootDiscriminator && !self.$__isSelected(path)) {
continue;
}
const value = obj[i];
if (!schemaType && strictRead && docSchema.pathType(path) === 'adhocOrUndefined') {
if (strictRead === 'throw') {
throw new StrictModeError(path, 'Field `' + path + '` is not in schema and strictRead is set to throw.');
} else if (strictRead === true) {
continue;
}
}
if (!schemaType && utils.isPOJO(value)) {
// assume nested object
if (!doc[i]) {
doc[i] = {};
if (!strict && !(i in docSchema.tree) && !(i in docSchema.methods) && !(i in docSchema.virtuals)) {
self[i] = doc[i];
} else if (opts?.virtuals && (i in docSchema.virtuals)) {
self[i] = doc[i];
}
}
init(self, value, doc[i], opts, path + '.');
} else if (!schemaType) {
// Handle strictRead: filter unknown fields during document hydration from DBView on GitHub (pinned to 49cdab0136)
Solutions
- Set `strictRead: true` instead of 'throw' so unknown fields are silently dropped on read
- Re-add the offending field to the schema (e.g. with `select: false`) until the data is migrated
- Migrate stored documents with an `$unset` update to strip stale fields
- Use a projection so unknown fields are never fetched
Example fix
// before
const schema = new Schema({ name: String }, { strictRead: 'throw' });
const docs = await Model.find(); // old docs still contain `legacyField` -> StrictModeError
// after (acknowledge the field, or drop it silently)
const schema = new Schema(
{ name: String, legacyField: { type: Schema.Types.Mixed, select: false } },
{ strictRead: 'throw' }
);
// or simply: { strictRead: true } Defensive patterns
Strategy: try-catch
Validate before calling
// Detect schema drift before hydrating raw objects
const known = new Set(Object.keys(MyModel.schema.paths).concat(['_id']));
const unknown = Object.keys(rawDoc).filter(k => !known.has(k));
if (unknown.length > 0) {
// strip or log unknown keys before strictRead: 'throw' sees them
for (const k of unknown) delete rawDoc[k];
} Type guard
function isKnownField(model, key) {
return key === '_id' || model.schema.path(key) != null;
} Try / catch
try {
const docs = await MyModel.find(query);
} catch (err) {
if (err instanceof mongoose.Error.StrictModeError) {
// stored data has fields the schema does not know; parse the path from err.message
// then either add the path to the schema or relax strictRead to true
} else {
throw err;
}
} Prevention
- When removing a field from a schema, ship a $unset migration in the same release
- Prefer strictRead: true unless a hard failure on unknown fields is the explicit goal
- Share one schema definition across all services that write the same collection
When it happens
Trigger: Running find()/findOne()/findById() or Model.hydrate() on a model whose schema (or hydration options) sets `strictRead: 'throw'` while stored documents carry fields not declared in the schema - e.g. fields dropped during a schema refactor, or extra keys written by another service sharing the collection.
Common situations: Schema evolution where old documents still store removed fields; multi-service collections with divergent schemas; enabling strictRead: 'throw' to audit legacy data hygiene; querying the base model when discriminator models define extra fields.
Related errors
- Field `${path}` is not in schema and strict mode is set to t
- Path "${path}" is not in schema, strict mode is `true`, and
- Field `${i}` is not in schema and strict mode is set to thro
- Field `${key}` is not in schema and strict mode is set to th
- Field `${path}` is not in schema and strict mode is set to t
AI-assisted analysis of Automattic/mongoose@49cdab0136 (2026-08-21).
Data as JSON: /api/errors/2f91a49758e35483.
Report an issue: GitHub.