{"record":{"id":"738e32194a14adbf","repo":"Automattic/mongoose","slug":"field-key-is-not-in-schema-and-strict-mode-is","errorCode":null,"errorMessage":"Field `${key}` is not in schema and strict mode is set to throw.","messagePattern":"Field `(.+?)` is not in schema and strict mode is set to throw\\.","errorType":"exception","errorClass":"StrictModeError","httpStatus":null,"severity":"error","filePath":"lib/document.js","lineNumber":1206,"sourceCode":"        if (constructing && valForKey === void 0 &&\n            this.$get(pathName) !== void 0) {\n          continue;\n        }\n\n        if (pathtype === 'adhocOrUndefined') {\n          pathtype = getEmbeddedDiscriminatorPath(this, pathName, { typeOnly: true });\n        }\n\n        if (pathtype === 'real' || pathtype === 'virtual') {\n          this.$set(pathName, valForKey, constructing, options);\n        } else if (pathtype === 'nested' && valForKey instanceof Document) {\n          this.$set(pathName,\n            valForKey.toObject({ transform: false }), constructing, options);\n        } else if (strict === 'throw') {\n          if (pathtype === 'nested') {\n            throw new ObjectExpectedError(key, valForKey);\n          } else {\n            throw new StrictModeError(key);\n          }\n        } else if (pathtype === 'nested' && valForKey == null) {\n          this.$set(pathName, valForKey, constructing, options);\n        }\n      } else {\n        this.$set(pathName, valForKey, constructing, options);\n      }\n    }\n\n    // Ensure all properties are in correct order\n    const orderedDoc = {};\n    const orderedKeys = Object.keys(this.$__schema.tree);\n    for (let i = 0, len = orderedKeys.length; i < len; ++i) {\n      (key = orderedKeys[i]) &&\n      (Object.hasOwn(this._doc, key)) &&\n      (orderedDoc[key] = undefined);\n    }\n    this._doc = Object.assign(orderedDoc, this._doc);","sourceCodeStart":1188,"sourceCodeEnd":1224,"githubUrl":"https://github.com/Automattic/mongoose/blob/49cdab01366679723b487ecb754b38570f783289/lib/document.js#L1188-L1224","documentation":"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.","triggerScenarios":"`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.","commonSituations":"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.","solutions":["Add the field to the schema if it is legitimate data","Fix the writer: correct the typo or strip unknown keys from the payload","Relax to `strict: true` (the default) if unknown keys should be silently dropped","Sanitize input objects with a schema-derived whitelist before set()"],"exampleFix":"// before\ndoc.set({ nmae: 'typo' }); // strict: 'throw' -> StrictModeError on `nmae`\n\n// after\ndoc.set({ name: 'correct' });\n// or whitelist first:\nconst known = new Set(Object.keys(MyModel.schema.paths).concat(['_id']));\ndoc.set(Object.fromEntries(Object.entries(body).filter(([k]) => known.has(k))));","handlingStrategy":"validation","validationCode":"// Whitelist payloads against schema paths before assignment\nconst schemaKeys = new Set(Object.keys(MyModel.schema.paths).concat(['_id']));\nfunction sanitize(payload) {\n  return Object.fromEntries(Object.entries(payload).filter(([k]) => schemaKeys.has(k)));\n}\ndoc.set(sanitize(req.body));","typeGuard":"function isKnownKey(model, k) {\n  return k === '_id' || model.schema.path(k) != null;\n}","tryCatchPattern":"try {\n  doc.set(req.body);\n} catch (err) {\n  if (err instanceof mongoose.Error.StrictModeError) {\n    // req.body contains a key not in the schema; the message names it\n  } else { throw err; }\n}","preventionTips":["Never pass client bodies straight into doc.set() or new Model(body)","Whitelist request payloads against schema paths at the API boundary","In tests, run with strict: 'throw' to surface unknown-key writes early"],"tags":["mongoose","strict-mode","schema","set"],"backgroundTag":"strict-mode-unknown-field","analyzedSha":"49cdab01366679723b487ecb754b38570f783289","analyzedAt":"2026-08-21T22:54:00.882Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}