Automattic/mongoose · error · TypeError

Collection name must be a string

Error message

Collection name must be a string

What it means

utils.toCollectionName() derives the collection name when registering a model. When a pluralization function is installed (Mongoose's default), the name must be a non-empty string; passing undefined, a number, a class, or any non-string as the model name throws a TypeError.

Source

Thrown at lib/utils.js:56

 * Produces a collection name from model `name`. By default, just returns
 * the model name
 *
 * @param {string} name a model name
 * @param {Function} pluralize function that pluralizes the collection name
 * @return {string} a collection name
 * @api private
 */

exports.toCollectionName = function(name, pluralize) {
  if (name === 'system.profile') {
    return name;
  }
  if (name === 'system.indexes') {
    return name;
  }
  if (typeof pluralize === 'function') {
    if (typeof name !== 'string') {
      throw new TypeError('Collection name must be a string');
    }
    if (name.length === 0) {
      throw new TypeError('Collection name cannot be empty');
    }
    return pluralize(name);
  }
  return name;
};

/**
 * Determines if `a` and `b` are deep equal.
 *
 * Modified from node/lib/assert.js
 *
 * @param {any} a a value to compare to `b`
 * @param {any} b a value to compare to `a`
 * @return {boolean}
 * @api private

View on GitHub (pinned to 49cdab0136)

Solutions

  1. Pass an explicit string name: mongoose.model('User', schema)
  2. Validate dynamic names before registration: if (typeof name !== 'string' || name.length === 0) throw ...
  3. Coerce numeric identifiers with String(name) if a numeric-looking name is intended

Example fix

// before
mongoose.model(process.env.USER_MODEL, schema); // undefined in env
// after
const name = process.env.USER_MODEL || 'User';
mongoose.model(name, schema);
Defensive patterns

Strategy: type-guard

Validate before calling

function registerModel(mongoose, name, schema) {
  if (typeof name !== 'string' || name.length === 0) throw new TypeError(`Model name must be a non-empty string, got ${typeof name}`);
  return mongoose.model(name, schema);
}

Type guard

function isValidModelName(name) { return typeof name === 'string' && name.length > 0; }

Try / catch

try { mongoose.model(name, schema); } catch (err) { if (/Collection name must be a string/.test(err.message)) throw new Error(`Invalid model name: ${String(name)} (${typeof name})`); throw err; }

Prevention

When it happens

Trigger: mongoose.model(undefined, schema) from an unset variable; mongoose.model(42, schema) with a numeric name; connection.model(SomeClass, schema) passing a class instead of its name; typos like mongoose.model(nane, schema).

Common situations: Dynamic model registration from config files or loops where the name variable is missing or numeric; minified/bundled code where an import resolves to undefined.

Related errors


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