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

View on GitHub (pinned to 49cdab0136)

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.