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
- Set an explicit 'as' option on the association so its alias differs from the conflicting attribute name.
- Rename the conflicting attribute (or its columnName) so the model attribute key no longer matches the association alias.
- If using decorators, rename the decorated class field so it does not collide with a declared attribute.
- 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
- Always pass an explicit 'as' that you have verified is not an attribute key.
- Centralize association declarations and review them in code review for attribute-name overlap.
- When using decorators, ensure field names differ from attribute names.
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
- You have defined two associations with the same name "${as}"
- The constraint name must be provided explicitly if one of Se
- ${parent ? `The association "${parent.as}" needs to define`
- Model ${model.name} must be defined (through Model.init or S
- ${source.name}.${lowerFirst(type.name)} was called with ${No
AI-assisted analysis of sequelize/sequelize@7e1deec499 (2026-08-03).
Data as JSON: /data/errors/de829111e8b618c4.json.
Report an issue: GitHub.