Skip to content

fix(xmtp_mls): enforce MAX_GROUP_SIZE in add_members (by inbox_id) - #4010

Open
teyrebaz33 wants to merge 2 commits into
xmtp:mainfrom
teyrebaz33:fix/max-group-size-add-members
Open

fix(xmtp_mls): enforce MAX_GROUP_SIZE in add_members (by inbox_id)#4010
teyrebaz33 wants to merge 2 commits into
xmtp:mainfrom
teyrebaz33:fix/max-group-size-add-members

Conversation

@teyrebaz33

@teyrebaz33 teyrebaz33 commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Fixes #4009

Problem

Group::add_members_by_identity enforces MAX_GROUP_SIZE (250) before queuing a membership update intent. Group::add_members -- the inbox_id-based counterpart -- had no equivalent check, so a group already at the 250-member cap could still be grown past the limit through this entry point.

Fix

Mirrors the existing add_members_by_identity guard: compute member_count via self.members(), return GroupError::UserLimitExceeded before building the intent if member_count + new_ids.len() > MAX_GROUP_SIZE. Un-ignores test_max_limit_add, which was disabled pending this fix.

Testing

  • cargo test -p xmtp_mls --release --lib groups::tests::test_max_limit_add -- previously failed (add succeeded when it should have errored, group ended up with 251 members), now passes.
  • Ran the full groups::tests suite (~720 tests) multiple times, with and without this change. A handful of unrelated tests intermittently fail when run as part of the full suite in parallel against the local backend (test_commit_log_remote::*, test_failed_installations::*, test_dm_creation_with_user_two_installations_one_malformed), but each passes reliably in isolation, and the specific failing set changes between runs. Verified the same intermittent behavior exists on unmodified main -- this is resource contention against the shared local backend under parallel load, not a regression from this change.
  • cargo clippy -p xmtp_mls --lib -- -D warnings: clean.

Note on process

I used AI assistance (Claude) to investigate the codebase and draft this fix, disclosed per your AI-contributions policy. I reviewed and understand the change, and independently verified the bug against a live backend before writing the fix.

Note

Enforce MAX_GROUP_SIZE limit in add_members before building membership update intent

  • Adds a preflight check in the membership update method that fetches the current member count and returns GroupError::UserLimitExceeded if adding the requested members would exceed MAX_GROUP_SIZE.
  • Updates test_max_limit_add in tests/mod.rs to run on native targets by replacing #[ignore] with #[cfg_attr(target_arch = "wasm32", ignore)].

Macroscope summarized 0766854.

add_members_by_identity already checked member_count + new members
against MAX_GROUP_SIZE (250) before queuing the membership update
intent. add_members -- the inbox_id-based counterpart used e.g. when
adding an already-registered member -- had no such check, so a group
already at the 250-member cap could still be grown past the limit
through this entry point.

Discovered via the ignored-test tracker: test_max_limit_add asserts
that adding a 251st member via add_members() returns an error once
the group already has 250 members (249 added via
add_members_by_identity + the group creator). Running it against a
live backend confirmed the bug directly -- the add succeeded and the
group ended up at 251 members instead of erroring.

Fix mirrors the existing add_members_by_identity guard: compute
current member_count via self.members(), and return
GroupError::UserLimitExceeded before building the membership update
intent if member_count + new_ids.len() > MAX_GROUP_SIZE. Un-ignores
test_max_limit_add.

Testing:
- cargo test -p xmtp_mls --release --lib groups::tests::test_max_limit_add
  -- previously failed (add succeeded when it should have errored),
  now passes.
- Ran the full groups::tests suite multiple times with and without
  this change. A handful of unrelated tests (test_commit_log_remote,
  test_failed_installations, test_dm_creation_with_user_two_installations_one_malformed)
  intermittently fail when run as part of the full ~720-test suite in
  parallel against the local backend, but each passes reliably when
  run in isolation, and the specific set of failures changes between
  runs -- consistent with resource contention against the shared
  local backend under parallel load, not a regression from this
  change. Verified by running the same subset against unmodified main
  and seeing the same intermittent behavior.
- cargo clippy -p xmtp_mls --lib -- -D warnings: clean.
@teyrebaz33
teyrebaz33 requested a review from a team as a code owner August 18, 2026 23:31
…tention

test_max_limit_add creates 250 real MLS clients to exercise the
MAX_GROUP_SIZE boundary. On native this runs reliably in ~15s.

On wasm, CI's parallel test-wasm job runs it alongside ~880 other
tests sharing one local backend + browser IndexedDB. Under that
contention the test consistently took 83-85s across all 4 nextest
retries and failed -- comfortably over the wasm-specific
slow-timeout (60s, see .config/nextest.toml). Running the test in
isolation on wasm (just wasm test-v3 -- test_max_limit_add) passes
reliably in ~13-27s, confirming this is contention-driven, not a
regression from the MAX_GROUP_SIZE fix itself (previously verified
extensively on native, see prior commit).

Uses the #[cfg_attr(target_arch = "wasm32", ignore)] pattern already
established elsewhere in this file (e.g.
add_missing_installs_reentrancy) for tests that are unsuited to the
parallel wasm CI profile. Native coverage remains full and is
sufficient to guard this regression.

Testing:
- cargo test -p xmtp_mls --release --lib groups::tests::test_max_limit_add
  -- still passes on native.
- just wasm test-v3 -- test_max_limit_add --nocapture -- passes in
  isolation on wasm (~13-27s), confirming the wasm CI failure was
  purely a parallel-suite timing issue, not a logic bug.
- cargo clippy -p xmtp_mls --lib -- -D warnings: clean.
@teyrebaz33

Copy link
Copy Markdown
Contributor Author

Pushed a follow-up commit: test_max_limit_add was failing in the test-wasm CI job (all 4 nextest retries, ~83-85s each), but passes reliably in isolation on wasm (~13-27s) and on native (~15s). This is resource contention from running a 250-client-creation test as part of the full ~880-test parallel wasm suite against one shared local backend, exceeding the wasm-specific 60s slow-timeout -- not a bug in the fix itself. Added #[cfg_attr(target_arch = \"wasm32\", ignore)], matching the existing pattern used for other heavy tests in this file (e.g. add_missing_installs_reentrancy). Native coverage remains full.

@teyrebaz33

Copy link
Copy Markdown
Contributor Author

The test-workspace failure on this run is the same known intermittent contention pattern, not related to this change -- this run also shows 15+ unrelated flaky tests (client::tests::should_reconnect, client::tests::test_key_package_rotation, xmtpv3::mls::tests::streaming::test_message_streaming_when_removed_then_added -- itself already tracked in #3877 -- and others across completely unrelated areas of the codebase), consistent with a generally contended CI run rather than anything specific to test_max_limit_add or this PR. test-wasm is green now after the previous fix. Would appreciate a re-run when convenient.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

add_members (by inbox_id) does not enforce MAX_GROUP_SIZE, unlike add_members_by_identity

1 participant