Skip to content

Bug Report: mongoose ObjectId constructor invoked without 'new' keyword causes TypeError #1596

@msakturkoglu

Description

@msakturkoglu

Bug Report: ObjectId constructor invoked without 'new' keyword causes TypeError

Description

When using @nestjs-query/query-mongoose with Mongoose 9.x, filtering by _id field throws a TypeError: Class constructor ObjectId cannot be invoked without 'new'.

Environment

  • @nestjs-query/query-mongoose: 0.30.0
  • mongoose: 9.1.2
  • @nestjs/mongoose: 11.0.4
  • Node.js: v22.x (or your version)

Steps to Reproduce

  1. Set up NestJS Query with Mongoose
  2. Define a DTO with @IDField() or @FilterableField() for _id field
  3. Execute a GraphQL query with filter on _id:
query {
  parks(filter: { _id: { eq: "b0000000000000000000000a" } }) {
    edges {
      node {
        _id
        name
      }
    }
  }
}

Error Stack Trace

TypeError: Class constructor ObjectId cannot be invoked without 'new'
    at ComparisonBuilder.convertToObjectId (/node_modules/@nestjs-query/query-mongoose/src/query/comparison.builder.ts:123:22)
    at ComparisonBuilder.convertQueryValue (/node_modules/@nestjs-query/query-mongoose/src/query/comparison.builder.ts:112:19)
    at ComparisonBuilder.build (/node_modules/@nestjs-query/query-mongoose/src/query/comparison.builder.ts:59:51)
    at WhereBuilder.withFilterComparison (/node_modules/@nestjs-query/query-mongoose/src/query/where.builder.ts:74:37)

Root Cause

In comparison.builder.js (line 82 in compiled version, line 123 in TypeScript source), the ObjectId constructor is called without the new keyword.

Current code (line 82 in dist/src/query/comparison.builder.js):

return mongoose_1.Types.ObjectId(val);

Should be:

return new mongoose_1.Types.ObjectId(val);

In modern JavaScript/TypeScript, class constructors like ObjectId must be invoked with the new keyword. Mongoose 9.x enforces this requirement strictly, whereas older versions may have been more lenient.

Temporary Workaround

Until this is fixed in the package, you can temporarily patch the compiled file:

  1. Navigate to node_modules/@nestjs-query/query-mongoose/dist/src/query/comparison.builder.js
  2. Find line 82 in the convertToObjectId method
  3. Change:
    return mongoose_1.Types.ObjectId(val);
    To:
    return new mongoose_1.Types.ObjectId(val);

Note: This workaround will be lost when reinstalling dependencies. Consider using a patch tool like patch-package to persist this fix.

Proposed Fix

Update src/query/comparison.builder.ts line 123 in the source code:

// Before
private convertToObjectId(val: string | number | (string | number)[]): any {
  if (Array.isArray(val)) {
    return val.map((v) => this.convertToObjectId(v));
  }
  if (typeof val === 'string' || typeof val === 'number') {
    if (Types.ObjectId.isValid(val)) {
      return Types.ObjectId(val);  // ❌ Missing 'new' keyword
    }
  }
  return val;
}

// After
private convertToObjectId(val: string | number | (string | number)[]): any {
  if (Array.isArray(val)) {
    return val.map((v) => this.convertToObjectId(v));
  }
  if (typeof val === 'string' || typeof val === 'number') {
    if (Types.ObjectId.isValid(val)) {
      return new Types.ObjectId(val);  // ✅ Added 'new' keyword
    }
  }
  return val;
}

Additional Context

  • This appears to be a regression or incompatibility with Mongoose 9.x where ObjectId constructor must be called with the new keyword
  • The issue occurs specifically when filtering on ObjectId fields (typically _id or other fields with @Prop({ type: Types.ObjectId }))
  • Other filtering operations on non-ObjectId fields work correctly
  • This likely affects all users running Mongoose 9.x with @nestjs-query/query-mongoose 0.30.0
  • The same pattern may exist in other parts of the codebase that instantiate ObjectId

Expected Behavior

Filtering by _id field (or any ObjectId field) should work without throwing TypeError. The query should execute successfully and return filtered results:

{
  "data": {
    "parks": {
      "edges": [
        {
          "node": {
            "_id": "b0000000000000000000000a",
            "name": "Park Name"
          }
        }
      ]
    }
  }
}

Actual Behavior

TypeError is thrown when attempting to filter by _id field, preventing any ObjectId-based filtering operations. The GraphQL query fails completely with:

TypeError: Class constructor ObjectId cannot be invoked without 'new'

This makes it impossible to filter documents by their ObjectId fields, which is a critical feature for MongoDB-based applications.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions