sequelize/sequelize · error · Error
Invalid option received for "inverse.type": ${options.invers
Error message
Invalid option received for "inverse.type": ${options.inverse.type} is not recognised. Expected "hasMany" or "hasOne" What it means
BelongsTo supports an `inverse` option that auto-creates the back-reference; `inverse.type` must be either `'hasMany'` or `'hasOne'`. In the constructor (belongs-to.ts:232) a switch on `options.inverse.type` falls through to a default that throws an Error for any other value. This is a defensive check for an invalid/typo'd inverse type.
Source
Thrown at packages/core/src/associations/belongs-to.ts:242
as: options.inverse.as,
scope: options.inverse?.scope,
sourceKey: options.targetKey,
inverse: undefined,
});
delete passDown.targetKey;
switch (options.inverse.type) {
case 'hasMany':
HasManyAssociation.associate(secret, target, source, passDown, this, this);
break;
case 'hasOne':
HasOneAssociation.associate(secret, target, source, passDown, this, this);
break;
default:
throw new Error(
`Invalid option received for "inverse.type": ${options.inverse.type} is not recognised. Expected "hasMany" or "hasOne"`,
);
}
}
}
static associate<
S extends Model,
T extends Model,
SourceKey extends AttributeNames<S>,
TargetKey extends AttributeNames<T>,
>(
secret: symbol,
source: ModelStatic<S>,
target: ModelStatic<T>,
options: BelongsToOptions<SourceKey, TargetKey> = {},
parent?: Association<any>,
): BelongsToAssociation<S, T, SourceKey, TargetKey> {View on GitHub (pinned to 7e1deec499)
Solutions
- Use `inverse: { type: 'hasMany' }` for a one-to-many back-reference.
- Use `inverse: { type: 'hasOne' }` for a one-to-one back-reference.
- Remove the `inverse` option if you don't need an auto-created back-association.
Example fix
// before
Comment.belongsTo(Post, { inverse: { type: 'belongsToMany' } });
// after
Comment.belongsTo(Post, { inverse: { type: 'hasMany', as: 'comments' } }); Defensive patterns
Strategy: type-guard
Type guard
const ALLOWED = new Set(['hasMany', 'hasOne']);
function isValidInverseType(options) {
return !options.inverse || options.inverse.type === undefined || ALLOWED.has(options.inverse.type);
}
if (!isValidInverseType(opts)) {
throw new Error(`inverse.type must be 'hasMany' or 'hasOne'`);
} Prevention
- Remember the inverse of a belongsTo can only be hasMany or hasOne — never belongsToMany.
- Use TypeScript's `BelongsToOptions` which types `inverse.type` as the union.
- Centralise inverse-type strings as constants to avoid typos.
When it happens
Trigger: `Comment.belongsTo(Post, { inverse: { type: 'belongsToMany' } })` or `inverse: { type: 'hasManyy' }` (typo) or any string other than the two allowed.
Common situations: Misunderstanding that the inverse of a belongsTo can only be hasMany or hasOne (not belongsToMany or another belongsTo); typo; passing a value from a generic variable.
Related errors
- Unknown attribute "${options.targetKey}" passed as targetKey
- Both options "as" and "inverse.as" must be defined for belon
- Both options "as" and "inverse.as" must be defined for hasOn
- Invalid options: "to" and "step" cannot both be specified.
- Invalid options: "to" and "step" cannot both be specified.
AI-assisted analysis of sequelize/sequelize@7e1deec499 (2026-08-03).
Data as JSON: /data/errors/e6c874d79084e7c4.json.
Report an issue: GitHub.