Automattic/mongoose · error · StrictModeError
Field `${path}` is not in schema and strict mode is set to t
Error message
Field `${path}` is not in schema and strict mode is set to throw. What it means
While casting an upsert, mongoose found a path that is not in the schema and strict mode resolved to 'throw'. StrictModeError exists to surface unknown fields instead of silently dropping them; the upsert flag makes any truthy strict setting fatal, and 'throw' produces this default message naming the field.
Source
Thrown at lib/cast.js:299
value = value.toObject({ virtuals: false });
}
}
}
_cast(value, numbertype, context);
continue;
}
}
if (schema.nested[path]) {
continue;
}
const strict = 'strict' in options ? options.strict : schema.options.strict;
const strictQuery = getStrictQuery(options, schema._userProvidedOptions, schema.options, context);
if (options.upsert && strict) {
if (strict === 'throw') {
throw new StrictModeError(path);
}
throw new StrictModeError(path, 'Path "' + path + '" is not in ' +
'schema, strict mode is `true`, and upsert is `true`.');
} if (strictQuery === 'throw') {
throw new StrictModeError(path, 'Path "' + path + '" is not in ' +
'schema and strictQuery is \'throw\'.');
} else if (strictQuery) {
delete obj[path];
}
} else if (val == null) {
continue;
} else if (utils.isPOJO(val)) {
any$conditionals = Object.keys(val).some(isOperator);
if (!any$conditionals) {
obj[path] = schematype.castForQuery(
null,
val,View on GitHub (pinned to 49cdab0136)
Solutions
- Declare the field in the schema (or fix the typo) so the path is known
- Strip unknown keys from the update document before calling updateOne with upsert: true
- Allow it for this call only: Model.updateOne(filter, update, { upsert: true, strict: false })
- Store genuinely schemaless extras under a declared Mixed path instead of top level
Example fix
// before
const schema = new Schema({ name: String }, { strict: 'throw' });
await Model.updateOne({ name: 'x' }, { name: 'x', counter: 1 }, { upsert: true });
// after
const schema = new Schema({ name: String, counter: Number }, { strict: 'throw' });
await Model.updateOne({ name: 'x' }, { name: 'x', counter: 1 }, { upsert: true }); Defensive patterns
Strategy: validation
Validate before calling
function findUnknownPaths(Model, doc) {
return Object.keys(doc).filter(
k => !(k in Model.schema.paths) && !Model.schema.nested[k]
);
}
const unknown = findUnknownPaths(Model, update);
if (unknown.length > 0 && opts.upsert) {
throw new Error(`Refusing upsert with unknown paths: ${unknown.join(', ')}`);
} Try / catch
try {
await Model.updateOne(filter, update, { upsert: true });
} catch (err) {
if (err.name === 'StrictModeError') {
// err.path names the unknown field; add it to the schema or delete it from `update`
}
throw err;
} Prevention
- Model every field you upsert; keep schema and API contract in sync
- Pick modeled fields explicitly instead of forwarding whole request bodies
- Run integration tests for each upsert endpoint so unknown fields fail in CI, not production
When it happens
Trigger: Model.updateOne(filter, { notInSchema: 1 }, { upsert: true }) on a schema defined with { strict: 'throw' }; the same via findOneAndUpdate; passing { strict: 'throw' } inside the options of a single call.
Common situations: Upserting API payloads that carry extra metadata (tenant id, client version) never added to the schema; field-name typos; payloads shared with insert paths that ran under strict: false; enabling strict: 'throw' during a data-hygiene audit.
Related errors
- Path "${path}" is not in schema, strict mode is `true`, and
- Field `${path}` is not in schema and strictRead is set to th
- 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/636d7a0695cf6f23.
Report an issue: GitHub.