jitsi/jitsi-meet · error · Error
A remote participant must be associated with a JitsiConferen
Error message
A remote participant must be associated with a JitsiConference!
What it means
participantJoined throws when it is called with a participant object that has no conference property, because remote participants are keyed by an id-conference pair in the participants reducer. This is a programmer/contract error inside the app (an invariant violation), not an environmental failure: the action creator requires every remote participant to be tied to a concrete JitsiConference instance.
Source
Thrown at react/features/base/participants/actions.ts:235
* type: PARTICIPANT_JOINED,
* participant: IParticipant
* }}
*/
export function participantJoined(participant: IParticipant) {
// Only the local participant is not identified with an id-conference pair.
if (participant.local) {
return {
type: PARTICIPANT_JOINED,
participant
};
}
// In other words, a remote participant is identified with an id-conference
// pair.
const { conference } = participant;
if (!conference) {
throw Error(
'A remote participant must be associated with a JitsiConference!');
}
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
// A remote participant is only expected to join in a joined or joining
// conference. The following check is really necessary because a
// JitsiConference may have moved into leaving but may still manage to
// sneak a PARTICIPANT_JOINED in if its leave is delayed for any purpose
// (which is not outrageous given that leaving involves network
// requests.)
const stateFeaturesBaseConference
= getState()['features/base/conference'];
if (conference === stateFeaturesBaseConference.conference
|| conference === stateFeaturesBaseConference.joining) {
return dispatch({
type: PARTICIPANT_JOINED,
participantView on GitHub (pinned to 98de6219cc)
Solutions
- Pass the JitsiConference instance on the participant: participantJoined(dispatch, { id, conference, ... }) — audit the call site listed in the stack trace.
- If the participant is genuinely local, use localParticipantJoined (or the local variant of the action) instead of participantJoined.
- When consuming USER_JOINED events, guard: if (!conference) return; before building the participant payload.
- If synthesizing virtual participants (screenshare/whiteboard), attach the active conference from redux state (getConference(state)).
Example fix
// before
participantJoined(fakeId, {
id: fakeId,
name: 'Virtual participant'
});
// after
participantJoined(fakeId, {
id: fakeId,
name: 'Virtual participant',
conference: getConference(store.getState())
}); Defensive patterns
Strategy: type-guard
Validate before calling
const isRemoteParticipantPayload = (p: { conference?: JitsiConference }) => Boolean(p.conference); Type guard
function isRemoteParticipant(p: { conference?: unknown }): p is { id: string; conference: JitsiConference } {
return typeof p.id === 'string' && p.conference instanceof Object && 'lock' in (p.conference as JitsiConference);
} Try / catch
try { dispatch(participantJoined(id, participant)); } catch (e) { logger.error('Malformed participant payload, missing conference', participant); } Prevention
- Always attach the active JitsiConference when building remote participant payloads.
- Use localParticipantJoined for local users; participantJoined only for remotes.
- Guard USER_JOINED handlers: skip events where conference is falsy.
- In tests, stub a minimal conference object on all participant fixtures.
When it happens
Trigger: Calling participantJoined({ id, ... }) without a conference field; constructing a fake/virtual participant manually and forgetting to attach the JitsiConference; lib-jitsi-meet firing USER_JOINED with a null/undefined conference argument (e.g., virtual screenshare or whiteboard synthetic joins in older versions).
Common situations: New integration code (e.g., custom virtual participants like the handleSharingVideoStatus or focusWhiteboard callers listed) that passes a plain object without conference; upgrading lib-jitsi-meet where the USER_JOINED payload shape changed; tests/mocks that create participants without a conference stub.
AI-assisted analysis of jitsi/jitsi-meet@98de6219cc (2026-08-28).
Data as JSON: /api/errors/02775698d0cf897e.
Report an issue: GitHub.