bug: Filtered /relations returns short pages without next_batch because the limit is applied before filters #2470
Labels
No labels
Abandoned
Blocked
Bug
Changelog
Added
Changelog
Missing
Changelog
None
Cherry-picking
Database
Dependencies
Dependencies/Renovate
Difficulty
Easy
Difficulty
Hard
Difficulty
Medium
Documentation
Enhancement
Good first issue
Help wanted
Inherited
Matrix/Administration
Matrix/Appservices
Matrix/Auth
Matrix/Client
Matrix/Core
Matrix/E2EE
Matrix/Federation
Matrix/Hydra
Matrix/MSC
Matrix/Media
Matrix/T&S
Merge
Merge/Manual
Merge/Squash
Meta
Meta/CI
Meta/Packaging
Priority
Blocking
Priority
High
Priority
Low
Security
Status
Confirmed
Status
Duplicate
Status
Invalid
Status
Needs Investigation
Support
bob the builder
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
continuwuation/continuwuity#2470
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What is the bug?
When
/relationsis called with arel_typeorevent_typefilter, the server can return a short page with nonext_batch, even though more matching relations exist. The client has no way to fetch the rest.This happens because the limit is applied before the filters.
pdu_metadata::get_relationscollects all direct relations, then walks deeper levels and stops once its result count reacheslimit(pdu_metadata/mod.rs#L108-L111). That count includes relations of every type. The filters only run afterwards, in the endpoint (relations.rs#L156-L171).Steps to reproduce
GET /_matrix/client/v1/rooms/{roomId}/relations/{T}/m.annotation?recurse=true&limit=5.next_batchif there are more. But you actually get at most 1 reaction and nonext_batch.Server name and version
federated.nexus + local repro,
02aed4fb23Additional context
.filter(|(_, pdu)| {filter_event_type.as_ref().is_none_or(|kind| kind == pdu.kind())}).filter(|(_, pdu)| {filter_rel_type.as_ref().is_none_or(|rel_type| rel_type.relation_type_equal(pdu))}).stream()pdus.push(relation);if pdus.len() >= limit {break 'limit;}