{"record":{"id":"5cd5c6437fa4ce0c","repo":"Automattic/mongoose","slug":"collection-name-must-be-a-string","errorCode":null,"errorMessage":"Collection name must be a string","messagePattern":"Collection name must be a string","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"lib/utils.js","lineNumber":56,"sourceCode":" * Produces a collection name from model `name`. By default, just returns\n * the model name\n *\n * @param {string} name a model name\n * @param {Function} pluralize function that pluralizes the collection name\n * @return {string} a collection name\n * @api private\n */\n\nexports.toCollectionName = function(name, pluralize) {\n  if (name === 'system.profile') {\n    return name;\n  }\n  if (name === 'system.indexes') {\n    return name;\n  }\n  if (typeof pluralize === 'function') {\n    if (typeof name !== 'string') {\n      throw new TypeError('Collection name must be a string');\n    }\n    if (name.length === 0) {\n      throw new TypeError('Collection name cannot be empty');\n    }\n    return pluralize(name);\n  }\n  return name;\n};\n\n/**\n * Determines if `a` and `b` are deep equal.\n *\n * Modified from node/lib/assert.js\n *\n * @param {any} a a value to compare to `b`\n * @param {any} b a value to compare to `a`\n * @return {boolean}\n * @api private","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/Automattic/mongoose/blob/49cdab01366679723b487ecb754b38570f783289/lib/utils.js#L38-L74","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Pass an explicit string name: mongoose.model('User', schema)","Validate dynamic names before registration: if (typeof name !== 'string' || name.length === 0) throw ...","Coerce numeric identifiers with String(name) if a numeric-looking name is intended"],"exampleFix":"// before\nmongoose.model(process.env.USER_MODEL, schema); // undefined in env\n// after\nconst name = process.env.USER_MODEL || 'User';\nmongoose.model(name, schema);","handlingStrategy":"type-guard","validationCode":"function registerModel(mongoose, name, schema) {\n  if (typeof name !== 'string' || name.length === 0) throw new TypeError(`Model name must be a non-empty string, got ${typeof name}`);\n  return mongoose.model(name, schema);\n}","typeGuard":"function isValidModelName(name) { return typeof name === 'string' && name.length > 0; }","tryCatchPattern":"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; }","preventionTips":["Default dynamic names explicitly: process.env.MODEL_NAME || 'User'","Fail fast on unset imports/variables used as model names","Type model-name parameters as string in TS to catch this at compile time"],"tags":["mongoose","model","collection-name","typeerror"],"backgroundTag":"invalid-model-name","analyzedSha":"49cdab01366679723b487ecb754b38570f783289","analyzedAt":"2026-08-21T22:54:00.882Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}