Skip to content

fix(context): bootstrap group metadata on join when not replicated locally#2092

Closed
chefsale wants to merge 1 commit intomasterfrom
cursor/group-context-invitation-0e96
Closed

fix(context): bootstrap group metadata on join when not replicated locally#2092
chefsale wants to merge 1 commit intomasterfrom
cursor/group-context-invitation-0e96

Conversation

@chefsale
Copy link
Copy Markdown
Member

[context] Fix group invitation join when group metadata is not replicated locally

Description

Fixes an edge case where joining a group via invitation fails when the joiner's node does not have the group metadata replicated locally. This commonly happens when:

  • A group is created without any contexts (no gossipsub topic to replicate through)
  • The joiner's node has never been connected to the group's P2P topic

Previously, join_group would immediately bail with:

"group metadata is missing locally; wait for group state to replicate before joining (local governance)"

This was a dead end — the joiner couldn't subscribe to receive group state because they weren't a member yet, and they couldn't become a member because they didn't have the group state.

The fix follows the same bootstrap pattern already used by join_context (lines 210-233 of join_context.rs):

  1. When group metadata is missing locally, create stub GroupMetaValue with the inviter as admin
  2. Add the inviter as an admin member so governance checks pass
  3. Subscribe to the group gossipsub topic
  4. Sign the JoinWithInvitationClaim governance op with a zero state hash (since the stub metadata won't match the admin's real state), which the receiving nodes accept per the existing zero-hash bypass in apply_local_signed_group_op

For the non-bootstrapped case (group metadata already replicated), the existing sign_apply_and_publish flow with real state hash is preserved.

Test plan

  • cargo check -p calimero-context — passes
  • cargo clippy -p calimero-context -- -A warnings — passes
  • cargo fmt --check — passes

Manual verification scenario:

  1. Create a group (no contexts attached)
  2. Create a group invitation on node 1
  3. On node 2, join the group using the invitation — previously failed with "group metadata is missing locally", now succeeds by bootstrapping stub metadata

Documentation update

None — this is a bug fix to an internal handler with no public API changes.

Open in Web Open in Cursor 

…cally

When a group is created without contexts, the joiner's node has no way
to receive the group metadata via P2P replication before attempting to
join. Previously this was a hard bail ("group metadata is missing
locally"), making it impossible to accept group invitations when the
group had no contexts.

Now, when group metadata is missing locally during join_group, we
bootstrap stub metadata (mirroring the pattern in join_context.rs),
add the inviter as admin, and subscribe to the group topic. The
JoinWithInvitationClaim governance op is signed with a zero state hash
so the admin's node accepts it without a state-hash mismatch.

Co-authored-by: Sandi Fatic <chefsale@users.noreply.github.com>
@cursor cursor Bot changed the title [context] Fix group invitation join when group metadata is not replicated locally fix(context): bootstrap group metadata on join when not replicated locally Mar 31, 2026
Copy link
Copy Markdown

@meroreviewer meroreviewer Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Code Reviewer

Reviewed by 1 agents | Quality score: 32% | Review time: 99.7s

💡 1 suggestions. See inline comments.


🤖 Generated by AI Code Reviewer | Review ID: review-d74331e2


if let Err(e) =
group_store::apply_local_signed_group_op(&datastore, &signed_op)
{
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Warning log missing group_id for correlation

The warning includes joiner_identity and error but omits group_id, making it harder to correlate with other group-related logs.

Suggested fix:

Add `%group_id` to the warn! fields: `warn!(%group_id, %joiner_identity, %e, "failed to apply...")`

@chefsale chefsale closed this Apr 1, 2026
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.

2 participants