Automattic/mongoose · error · ObjectParameterError

Parameter "obj" to Document() must be an object, got "${obj}

Error message

Parameter "obj" to Document() must be an object, got "${obj}" (type ${typeof obj})

What it means

The Document constructor validates that its first argument is an object (or null/undefined) before applying paths and defaults. Passing any primitive — string, number, boolean — throws ObjectParameterError, and the message embeds the received value and its typeof so the offending input is identifiable.

Source

Thrown at lib/document.js:126

    fields = options;
    skipId = options.skipId;
  }

  // Avoid setting `isNew` to `true`, because it is `true` by default
  if (options.isNew != null && options.isNew !== true) {
    this.$isNew = options.isNew;
  }

  if (options.priorDoc != null) {
    this.$__.priorDoc = options.priorDoc;
  }

  if (skipId) {
    this.$__.skipId = skipId;
  }

  if (obj != null && typeof obj !== 'object') {
    throw new ObjectParameterError(obj, 'obj', 'Document');
  }

  let defaults = true;
  if (options.defaults !== undefined) {
    this.$__.defaults = options.defaults;
    defaults = options.defaults;
  }

  const schema = this.$__schema;

  if (typeof fields === 'boolean' || fields === 'throw') {
    if (fields !== true) {
      this.$__.strictMode = fields;
    }
    fields = undefined;
  } else if (options.strict !== undefined) {
    this.$__.strictMode = options.strict;
  } else if (schema.options.strict !== true) {

View on GitHub (pinned to 49cdab0136)

Solutions

  1. Validate the payload shape before constructing: if (typeof body === 'string') body = JSON.parse(body)
  2. Fix body parsing: register a JSON body parser and send Content-Type: application/json from clients
  3. Null and undefined are accepted — pass undefined rather than an empty string when there is no data

Example fix

// before
// client sent text/plain, express.json() not configured → req.body is a string
const user = new User(req.body);

// after
app.use(express.json()); // and client sends Content-Type: application/json
const user = new User(req.body);
Defensive patterns

Strategy: type-guard

Validate before calling

const isRecord = (v) => v != null && typeof v === 'object' && !Array.isArray(v);
if (!isRecord(payload)) {
  throw new TypeError('payload must be an object, got ' + typeof payload);
}
const doc = new MyModel(payload);

Type guard

const isPlainishObject = (v) =>
  v != null && typeof v === 'object' && !Array.isArray(v) && v.constructor === Object;

Try / catch

try {
  doc = new MyModel(input);
} catch (err) {
  if (err.name === 'ObjectParameterError') {
    return res.status(400).json({ error: 'body must be a JSON object' });
  }
  throw err;
}

Prevention

When it happens

Trigger: new MyModel('foo'), new MyModel(42), or new MyModel(JSON.stringify(data)) — constructing a document from a non-object value.

Common situations: Request bodies arriving as strings because of missing express.json()/wrong Content-Type; a failed JSON.parse upstream; CSV/Excel importers that end up passing strings; forwarding a querystring like 'a=1&b=2'.

Understand the failure class

Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.

Related errors


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