openclaw/openclaw · error · Error
Missing Buzz room membership for ${channelId}
Error message
Missing Buzz room membership for ${channelId} What it means
Thrown inside refreshMembership when the baseline membership for a channelId is absent from the memberships map. refreshMembership is only valid for channels already seeded with an initial membership; calling it for an unseeded or evicted channel is an internal invariant violation.
Source
Thrown at extensions/buzz/src/room-membership-tracker.ts:161
await queryBuzzRoomMemberships({
relay: params.relay,
relayPublicKey: params.relayPublicKey,
channelIds: [channelId],
signal: params.signal,
})
).get(channelId),
);
membershipQueryTail = query.then(
() => undefined,
() => undefined,
);
return query;
};
const refreshMembership = async (channelId: string, state: RefreshState): Promise<void> => {
const baseline = memberships.get(channelId);
if (!baseline) {
throw new Error(`Missing Buzz room membership for ${channelId}`);
}
for (const delayMs of MEMBERSHIP_REFRESH_DELAYS_MS) {
const generation = state.generation;
state.lastAttemptedGeneration = generation;
await sleepWithSignal(delayMs, params.signal);
if (state.generation !== generation) {
continue;
}
let refreshed: BuzzRoomMembership | undefined;
try {
refreshed = await queryMembership(channelId);
} catch (error) {
if (params.signal?.aborted) {
throw error;
}
continue;
}
if (state.generation !== generation || !refreshed) {View on GitHub (pinned to 01804a7531)
Solutions
- Ensure initial memberships for all configured channelIds are loaded before scheduling refreshes.
- Guard refresh scheduling against rooms removed from the active configuration.
- Treat a missing baseline as a no-op (skip refresh) rather than throwing if the room is no longer configured.
Example fix
// before
const baseline = memberships.get(channelId);
if (!baseline) {
throw new Error(`Missing Buzz room membership for ${channelId}`);
}
// after - skip refresh for unseeded/evicted rooms
const baseline = memberships.get(channelId);
if (!baseline) {
return; // room no longer tracked; nothing to refresh
} Defensive patterns
Strategy: validation
Validate before calling
function hasBaselineMembership(
memberships: Map<string, unknown>,
channelId: string,
): boolean {
return memberships.has(channelId);
}
if (!hasBaselineMembership(memberships, channelId)) {
// seed membership or skip refresh
} Prevention
- Always seed memberships for all configured channels before scheduling refreshes.
- Cancel in-flight refreshes when a room is removed from the active configuration.
- Treat a missing baseline as a no-op refresh rather than a fatal error.
When it happens
Trigger: refreshMembership invoked for a channelId whose membership was never loaded, was deleted, or whose initial load failed before refresh started. Indicates a lifecycle/ordering bug in the tracker rather than user input.
Common situations: A race where a room is removed from the configured set concurrently with a pending refresh, or a prior startup failure left the memberships map partially populated.
Related errors
- Buzz room membership is unavailable; retry after the room di
- Buzz QA file credentials are unavailable.
- Buzz QA could not resolve the portable id for native message
- Buzz bot no longer has the Bot role in room ${channelId}
- Could not refresh Buzz room membership for ${channelId}
AI-assisted analysis of openclaw/openclaw@01804a7531 (2026-08-12).
Data as JSON: /api/errors/8c1a980130b13280.
Report an issue: GitHub.