sequelize/sequelize · error · Error

Naming collision between attribute '${associationName}' and

Error message

Naming collision between attribute '${associationName}' and association '${associationName}' on model ${source.name}. To remedy this, change the "as" options in your association definition

What it means

Thrown by checkNamingCollision when an association's resolved name (the 'as' value) exactly matches the name of an already-defined attribute on the same source model. Sequelize injects association accessors/getters as properties on model instances, so a name clash would silently overwrite the attribute getter and produce corrupt queries. The error is raised eagerly (before construction at helpers.ts:209 and again after at helpers.ts:246) to prevent ambiguous property resolution.

Source

Thrown at packages/core/src/associations/helpers.ts:26

import { AssociationError } from '../errors/index.js';
import type { Model, ModelStatic } from '../model';
import type { Sequelize } from '../sequelize';
import * as deprecations from '../utils/deprecations.js';
import { isModelStatic, isSameInitialModel } from '../utils/model-utils.js';
import { removeUndefined } from '../utils/object.js';
import { pluralize, singularize } from '../utils/string.js';
import type { OmitConstructors } from '../utils/types.js';
import type {
  Association,
  AssociationOptions,
  ForeignKeyOptions,
  NormalizedAssociationOptions,
} from './base';
import type { ThroughOptions } from './belongs-to-many.js';

export function checkNamingCollision(source: ModelStatic<any>, associationName: string): void {
  if (Object.hasOwn(source.getAttributes(), associationName)) {
    throw new Error(
      `Naming collision between attribute '${associationName}'` +
        ` and association '${associationName}' on model ${source.name}` +
        '. To remedy this, change the "as" options in your association definition',
    );
  }
}

/**
 * Mixin (inject) association methods to model prototype
 *
 * @private
 *
 * @param association instance
 * @param mixinTargetPrototype Model prototype
 * @param methods Method names to inject
 * @param aliases Mapping between model and association method names
 */
export function mixinMethods<A extends Association, Aliases extends Record<string, string>>(

View on GitHub (pinned to 7e1deec499)

Solutions

  1. Set an explicit 'as' option on the association so its alias differs from the conflicting attribute name.
  2. Rename the conflicting attribute (or its columnName) so the model attribute key no longer matches the association alias.
  3. If using decorators, rename the decorated class field so it does not collide with a declared attribute.
  4. Audit source.getAttributes() keys vs the resolved 'as' to confirm which name is colliding.

Example fix

// before
User.init({ profile: DataTypes.STRING }, ...);
User.belongsTo(Profile, { foreignKey: 'profileId' }); // 'profile' alias collides with attribute 'profile'

// after
User.belongsTo(Profile, { as: 'userProfile', foreignKey: 'profileId' });
Defensive patterns

Strategy: validation

Validate before calling

import type { ModelStatic } from '@sequelize/core';

function assertNoAssociationNameCollision(
  source: ModelStatic<any>,
  as: string,
): void {
  const attrs = source.getAttributes();
  if (Object.prototype.hasOwnProperty.call(attrs, as)) {
    throw new Error(`Proposed association alias '${as}' collides with existing attribute on ${source.name}`);
  }
}

// call before defining the association
assertNoAssociationNameCollision(User, 'profile');
User.belongsTo(Profile, { as: 'profile', foreignKey: 'profileId' });

Prevention

When it happens

Trigger: Calling Source.hasMany(Target) / Source.belongsTo(Target) / etc. where the computed association alias equals an attribute key returned by source.getAttributes(). The alias is computed from options.as, or when omitted from the target model's singular/plural name (see normalizeBaseAssociationOptions, helpers.ts:294-313). Also triggered by association decorators whose field name matches an attribute.

Common situations: Defining a belongsTo to a 'User' target that resolves to alias 'user' while the source already has a column literally named 'user'. Singularizing/pluralizing producing an alias that collides with a foreignKey whose name matches. Mixing association decorators with attributes of the same field name.

Related errors


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