sequelize/sequelize · error · TypeError

Symbol attributes are not supported

Error message

Symbol attributes are not supported

What it means

At model-definition.ts:273-276 the constructor iterates the attributes object using `getAllOwnEntries`, which can surface Symbol keys. If an attribute key is a symbol rather than a string, a TypeError is thrown because Sequelize attributes must be named by strings (they become column references, query keys, and JS property names).

Source

Thrown at packages/core/src/model-definition.ts:275

        }),
      ),
    );

    // error check options
    for (const [validatorName, validator] of getAllOwnEntries(this.options.validate)) {
      if (typeof validator !== 'function') {
        throw new TypeError(
          `Members of the validate option must be functions. Model: ${this.modelName}, error with validate member ${String(validatorName)}`,
        );
      }
    }

    // attributes that will be added at the start of this.rawAttributes (id)
    const rawAttributes = pojo<{ [attributeName: string]: AttributeOptions<M> }>();

    for (const [attributeName, rawAttributeOrDataType] of getAllOwnEntries(attributesOptions)) {
      if (typeof attributeName === 'symbol') {
        throw new TypeError('Symbol attributes are not supported');
      }

      let rawAttribute: AttributeOptions<M>;
      try {
        rawAttribute = this.sequelize.normalizeAttribute(rawAttributeOrDataType);
      } catch (error) {
        throw new BaseError(
          `An error occurred for attribute ${attributeName} on model ${this.modelName}.`,
          { cause: error },
        );
      }

      rawAttributes[attributeName] = rawAttribute;

      if (rawAttribute.field) {
        fieldToColumn();
      }
    }

View on GitHub (pinned to 7e1deec499)

Solutions

  1. Use plain string keys for all attributes.
  2. Strip symbol keys before passing the attributes object to init/define.

Example fix

// before
User.init({ [Symbol('id')]: { type: DataTypes.INTEGER, primaryKey: true } }, { sequelize, modelName: 'User' });

// after
User.init({ id: { type: DataTypes.INTEGER, primaryKey: true } }, { sequelize, modelName: 'User' });
Defensive patterns

Strategy: type-guard

Validate before calling

function assertStringKeys(attrs) {
  for (const key of Reflect.ownKeys(attrs)) {
    if (typeof key !== 'string') {
      throw new Error(`Attribute key must be a string, got ${String(key)}.`);
    }
  }
}
assertStringKeys(attributes);

Type guard

function hasOnlyStringKeys(obj) {
  return Reflect.ownKeys(obj).every(k => typeof k === 'string');
}

Prevention

When it happens

Trigger: Defining attributes with a computed Symbol key, e.g. `User.init({ [Symbol('x')]: DataTypes.STRING }, ...)`; spreading a map/object whose own keys include a symbol.

Common situations: Programmatic attribute generation using symbols as keys; mixing framework metadata symbols into the attribute definition object.

Related errors


AI-assisted analysis of sequelize/sequelize@7e1deec499 (2026-08-03). Data as JSON: /data/errors/f02c41c783760c5b.json. Report an issue: GitHub.