Skip to content

fix: aggregatePaginated ignores explicit zero-value pagination options #40150

@CodeUltr0n

Description

@CodeUltr0n

Description

The aggregatePaginated method in packages/models/src/models/BaseRaw.ts applies $skip and $limit using truthy checks:

if (options.skip) { ... }
if (options.limit) { ... }

Steps to reproduce:

  1. Call any API or internal method that relies on aggregatePaginated with pagination options including skip: 0 or limit: 0.

  2. For example, construct an aggregation query with:

    {
      skip: 0,
      limit: 10
    }
  3. Observe the generated aggregation pipeline inside aggregatePaginated.

  4. Notice that $skip is not applied when skip is 0.

  5. As a result, the query does not behave consistently with expected pagination logic.

Call `aggregatePaginated` with:

aggregatePaginated(pipeline, {
  skip: 0,
  limit: 10,
});

Expected behavior:

Pagination options should be applied when explicitly defined, including zero values.

{ $skip: 0 }

Actual behavior:

The $skip stage is omitted when skip: 0 is passed, because the code uses a falsy check (if (options.skip)).

This causes valid zero-value pagination parameters to be ignored, resulting in inconsistent query behavior.

Server Setup Information

  • Version of Rocket.Chat Server: develop / current main branch source checkout
  • License Type: Not applicable for source-level issue
  • Number of Users: Not applicable
  • Operating System: macOS
  • Deployment Method: local source checkout
  • Number of Running Instances: 1 local development instance expected
  • DB Replicaset Oplog: not required to identify the bug from source
  • NodeJS Version: 22.16.0
  • MongoDB Version: not required to identify the bug from source

Client Setup Information

  • Desktop App or Browser Version: Not applicable
  • Operating System: macOS

Additional context

This issue is identifiable directly from source without depending on a specific deployment setup.

The aggregatePaginated method in
packages/models/src/models/BaseRaw.ts currently uses truthy checks for pagination options:

if (options.skip) {
	paginationPipeline.push({ $skip: options.skip });
}
if (options.limit) {
	paginationPipeline.push({ $limit: options.limit });
}

This causes explicit zero values such as skip: 0 and limit: 0 to be treated as if the option was not provided.

For aggregation-backed pagination paths, this can lead to inconsistent behavior compared with non-aggregation pagination.

This is particularly relevant for Activity Hub-related global fetch support, as those endpoints rely on aggregation-based pagination.

Relevant logs:

No runtime server logs are required to identify this bug.

The issue is verifiable directly from source:

packages/models/src/models/BaseRaw.ts

Optional local test attempt note

Local execution of:

yarn workspace @rocket.chat/meteor testapi

was blocked before test execution due to missing built workspace artifacts, for example:

Cannot find module '.../packages/models/dist/index.js'

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions