sequelize/sequelize · error · Error

Attribute ${attributeName} on model ${model.name} cannot hav

Error message

Attribute ${attributeName} on model ${model.name} cannot have both 'insertBefore' and 'insertAfter' set to true.

What it means

Thrown while computing registered attribute options for a child model when an inherited parent attribute has both `insertBefore: true` and `insertAfter: true`. These flags control column ordering relative to other inherited columns; setting both is contradictory and the attribute-ordering algorithm cannot decide where to place the column, so it refuses.

Source

Thrown at packages/core/src/decorators/shared/model.ts:217

  return modelOptions;
}

function getRegisteredAttributeOptions(model: ModelStatic): RegisteredAttributeOptions {
  const descendantAttributes: RegisteredAttributeOptions = {
    ...(registeredOptions.get(model)?.attributes ?? EMPTY_OBJECT),
  };
  const insertAfterAttributes: RegisteredAttributeOptions = {};
  const insertBeforeAttributes: RegisteredAttributeOptions = {};

  const parentModel = Object.getPrototypeOf(model);
  if (isModelStatic(parentModel)) {
    const parentAttributes: RegisteredAttributeOptions = getRegisteredAttributeOptions(parentModel);

    for (const attributeName of Object.keys(parentAttributes)) {
      const parentAttribute = { ...parentAttributes[attributeName] };
      if (parentAttribute.insertBefore && parentAttribute.insertAfter) {
        throw new Error(
          `Attribute ${attributeName} on model ${model.name} cannot have both 'insertBefore' and 'insertAfter' set to true.`,
        );
      }

      if (parentAttribute.type) {
        if (typeof parentAttribute.type === 'function') {
          parentAttribute.type = new parentAttribute.type();
        } else {
          parentAttribute.type = cloneDataType(parentAttribute.type);
        }
      }

      // options that must be cloned
      parentAttribute.unique = cloneDeep(parentAttribute.unique);
      parentAttribute.index = cloneDeep(parentAttribute.index);
      parentAttribute.references = cloneDeep(parentAttribute.references);
      parentAttribute.validate = cloneDeep(parentAttribute.validate);

View on GitHub (pinned to 7e1deec499)

Solutions

  1. Choose a single positioning strategy for the parent attribute: either insertBefore or insertAfter, not both.
  2. If the column ordering requirement genuinely needs both, restructure the model so the column is defined once in the desired position.
  3. Audit the parent/abstract model's attribute decorators for the flagged attribute name and remove one of the two ordering options.

Example fix

// before
abstract class Base extends Model {
  @Attribute({ type: DataTypes.STRING, insertBefore: true, insertAfter: true })
  status: string;
}

// after
abstract class Base extends Model {
  @Attribute({ type: DataTypes.STRING, insertBefore: true })
  status: string;
}
Defensive patterns

Strategy: validation

Validate before calling

// Ensure no attribute has both insertBefore and insertAfter.
function assertExclusivePositioning(attr: { insertBefore?: boolean; insertAfter?: boolean }) {
  if (attr.insertBefore && attr.insertAfter) {
    throw new Error('Attribute cannot have both insertBefore and insertAfter');
  }
}
assertExclusivePositioning(baseAttr);

Prevention

When it happens

Trigger: On an abstract/parent model, decorating an attribute with both @Before (or the insertBefore option) and @After (or insertAfter). The error surfaces when a concrete child class initializes and inherits that parent attribute, because ordering is computed at child-init time.

Common situations: Trying to force a column to appear in two positions. Copying decorator stacks from another column and not noticing the conflicting ordering decorators. Misunderstanding the insertBefore/insertAfter semantics as additive.

Related errors


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