Skip to content

Model.bulkSave() type error with custom string _id after #15688 changed Document default to ObjectId #16032

@nikzanda

Description

@nikzanda

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the bug has not already been reported

Mongoose version

8.23.0

Node.js version

24.13.0

MongoDB server version

6.0.2

Typescript version (if applicable)

5.9.3

Description

Current behavior

After PR #15688 changed the default generic parameter of Document<T> from unknown to Types.ObjectId, calling Model.bulkSave() on models with a custom string _id produces a TypeScript error:

  TS2345: Argument of type 'Array<HydratedDocument<IEmail, IEmailVirtuals>>'
  is not assignable to parameter of type 'Array<Document>'.
    Types of property '_id' are incompatible.
      Type 'string' is not assignable to type 'ObjectId'.

This worked correctly in mongoose 8.18.x where Document<T = unknown> accepted any _id type.

Expected behavior

Model.bulkSave() should accept documents from models that use a non-ObjectId _id (e.g., string, number, uuid), since Mongoose explicitly supports custom _id types.

Steps to Reproduce

import { Schema, model, connect, SchemaTypes, HydratedDocument, Model } from 'mongoose';

  interface IEmail {
    _id: string; // custom string _id (e.g. email messageId)
    to: string;
    subject: string;
  }

  type EmailInstance = HydratedDocument<IEmail>;
  type EmailModelType = Model<IEmail, {}, {}, {}, EmailInstance>;

  const emailSchema = new Schema<IEmail, EmailModelType>({
    _id: { type: SchemaTypes.String, required: true },
    to: { type: SchemaTypes.String, required: true },
    subject: { type: SchemaTypes.String, required: true },
  }, { _id: false });

  const Email = model<IEmail, EmailModelType>('Email', emailSchema);

  async function main() {
    await connect('mongodb://localhost:27017/test');

    const emails: EmailInstance[] = [
      new Email({ _id: 'msg-001', to: '[email protected]', subject: 'Hello' }),
      new Email({ _id: 'msg-002', to: '[email protected]', subject: 'World' }),
    ];

    // TS2345: Type 'string' is not assignable to type 'ObjectId'
    await Email.bulkSave(emails);
  }

In types/models.d.ts, bulkSave is typed as:

bulkSave(documents: Array, options?: MongooseBulkSaveOptions): Promise;

Since #15688 changed Document's default from unknown to Types.ObjectId:

  // Before #15688 (8.18.x) — works with any _id type
  class Document<T = unknown, ...>

  // After #15688 (8.20+) — only accepts ObjectId _id
  class Document<T = Types.ObjectId, ...>

The bare Document in bulkSave's signature now resolves to Document<Types.ObjectId>, rejecting any document with a non-ObjectId _id.

Expected Behavior

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    has repro scriptThere is a repro script, the Mongoose devs need to confirm that it reproduces the issuetypescriptTypes or Types-test related issue / Pull Request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions