Automattic/mongoose · error · StrictModeError
Path "${path}" is not in schema and strictQuery is 'throw'.
Error message
Path "${path}" is not in schema and strictQuery is 'throw'. What it means
strictQuery controls how mongoose handles query conditions on paths missing from the schema. When it resolves to 'throw', cast() raises StrictModeError naming the path instead of ignoring the condition (plain true would silently delete it). This fires from find/update calls whose filter references an unknown path.
Source
Thrown at lib/cast.js:304
_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,
context
);
} else {
const ks = Object.keys(val);
let $cond;View on GitHub (pinned to 49cdab0136)
Solutions
- Fix the filter: add the field to the schema or correct the typo
- Allow unmodeled filters per query with .setOptions({ strictQuery: false }) or globally with mongoose.set('strictQuery', false)
- Whitelist filter keys against Object.keys(Model.schema.paths) before querying
Example fix
// before
const schema = new Schema({ name: String }, { strictQuery: 'throw' });
await Model.find({ nam: 'x' }); // typo -> throws
// after
await Model.find({ name: 'x' }); Defensive patterns
Strategy: validation
Validate before calling
function pickKnownFilterKeys(Model, filter) {
const out = {};
for (const k of Object.keys(filter)) {
if (k in Model.schema.paths || k.startsWith('$')) out[k] = filter[k];
}
return out;
}
await Model.find(pickKnownFilterKeys(Model, req.query)); Try / catch
try {
await Model.find(filter);
} catch (err) {
if (err.name === 'StrictModeError' && /strictQuery/.test(err.message)) {
// err.path is the unknown filter field; whitelist it, fix the typo, or relax strictQuery
}
throw err;
} Prevention
- Map user-supplied filters through an allow-list of modeled fields
- Keep strictQuery: 'throw' in dev/test to surface filter typos early
- After field renames, grep for old field names in query builders
When it happens
Trigger: Model.find({ notInSchema: 1 }) with schema or query strictQuery: 'throw'; Model.findOneAndUpdate({ typoField: 'x' }, update) with the same setting; mongoose.set('strictQuery', 'throw') globally combined with user-supplied filters.
Common situations: Migrations between mongoose majors where strictQuery defaults changed, so previously-ignored filters start throwing once 'throw' is set; search endpoints forwarding arbitrary filter keys; renamed schema fields while old clients send old names; enabling 'throw' deliberately to catch filter typos.
Related errors
- Could not find path "${filterPath}" in schema
- Cast to string failed for value "${value}" (type ${valueType
- Invalid addFields() argument. Must be an object
- Aggregate `near()` must be called with non-nullish argument
- Invalid sort() argument. Must be a string or object.
AI-assisted analysis of Automattic/mongoose@49cdab0136 (2026-08-21).
Data as JSON: /api/errors/5581a97d364c0ec9.
Report an issue: GitHub.