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

  1. Use `inverse: { type: 'hasMany' }` for a one-to-many back-reference.
  2. Use `inverse: { type: 'hasOne' }` for a one-to-one back-reference.
  3. 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

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


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