Automattic/mongoose · error · Error

`enum` can only be set on an array of strings or numbers …

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.

Solutions

  1. Give the array an explicit primitive element type: `{ type: [String], enum: ['a','b'] }` or `{ type: [Number], enum: [1,2,3] }`.
  2. For ObjectId/Date arrays, replace enum with a custom validator on the element type.
  3. 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

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


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

Appendix: 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} value

View on GitHub (pinned to 49cdab0136)