Automattic/mongoose · error · Error
`enum` can only be set on an array of strings or numbers , n
Error message
`enum` can only be set on an array of strings or numbers , not ${instance} What it means
SchemaArray#enum walks through nested arrays to the innermost embedded schema type and requires its instance to be String or Number - enum is a value whitelist, which only makes sense for primitives. Any other element type (Mixed, ObjectId, Date, Boolean, subdocuments) is rejected when enum is set.
Source
Thrown at lib/schema/array.js:263
/**
* Adds an enum validator if this is an array of strings or numbers. Equivalent to
* `SchemaString.prototype.enum()` or `SchemaNumber.prototype.enum()`
*
* @param {...string|object} [args] enumeration values
* @return {SchemaArray} this
*/
SchemaArray.prototype.enum = function() {
let arr = this;
while (true) {
const instance = arr?.embeddedSchemaType?.instance;
if (instance === 'Array') {
arr = arr.embeddedSchemaType;
continue;
}
if (instance !== 'String' && instance !== 'Number') {
throw new Error('`enum` can only be set on an array of strings or numbers ' +
', not ' + instance);
}
break;
}
let enumArray = arguments;
if (!Array.isArray(arguments) && utils.isObject(arguments)) {
enumArray = utils.object.vals(enumArray);
}
arr.embeddedSchemaType.enum.apply(arr.embeddedSchemaType, enumArray);
return this;
};
/**
* Overrides the getters application for the population special-case
*
* @param {object} valueView on GitHub (pinned to 49cdab0136)
Solutions
- Give the array an explicit primitive element type: `{ type: [String], enum: ['a','b'] }` or `{ type: [Number], enum: [1,2,3] }`.
- For ObjectId/Date arrays, replace enum with a custom validator on the element type.
- Remember enum validates every element, not the array as a whole - use a custom array-level validator for whole-list rules.
Example fix
// before
const s = new Schema({ tags: { type: [], enum: ['red', 'blue'] } }); // [] -> Mixed elements
// after
const s = new Schema({ tags: { type: [String], enum: ['red', 'blue'] } }); Defensive patterns
Strategy: validation
Validate before calling
const enumCompatible = (schema, pathName) => {
let t = schema.path(pathName);
while (t?.$isMongooseArray) t = t.embeddedSchemaType;
return t?.instance === 'String' || t?.instance === 'Number';
};
if (!enumCompatible(schema, 'tags')) throw new Error('enum needs [String] or [Number] elements'); Prevention
- Always declare element types for arrays that carry enum ([String], [Number]) - never bare [].
- Use a custom validator when whitelisting non-primitive element types.
- Remember enum applies per element, not to the array as a whole.
When it happens
Trigger: `{ tags: { type: [], enum: ['a','b'] } }` (a bare [] means an array of Mixed); `{ ids: { type: [Schema.Types.ObjectId], enum: [...] } }`; an explicit `schema.path('when').enum(...)` on an array of Dates; enum on an array of subdocuments.
Common situations: Declaring arrays as bare [] and assuming string elements; intending allowed-values checks for ObjectId arrays; copying an enum option from a scalar field onto a non-string array.
Related errors
- Path "${path}" is not an array
- You can only add an embedded discriminator on a document arr
- Cannot set populate virtual as a property of an array
- Reference virtuals require `localField` option
- Reference virtuals require `foreignField` option
AI-assisted analysis of Automattic/mongoose@49cdab0136 (2026-08-21).
Data as JSON: /api/errors/23a215d0b2dedc88.
Report an issue: GitHub.