Problem
When a participant's partner drops out of a video call, FixAV misdiagnoses the problem as a device issue (speakerNotSet) rather than recognizing that no remote participants are subscribed. This sends users down a futile device-fix path instead of surfacing the actual problem: their partner isn't in the call.
Evidence (Sentry event 83d27b6b, Feb 27)
A Listener in a 6-player storytelling study had their paired Storyteller drop out. The subscription system correctly set all 4 remaining remote participants to {audio: false, video: false} (none were the partner). But when the user reported "cant-see, cant-hear":
- FixAV diagnosed
speakerNotSet (because callObject.getOutputDevices() returned null)
- Attempted speaker re-alignment — reported "success"
- Validation showed
speakerNotSet still present
- Error reported to Sentry as a device failure
The real problem was never audio devices — it was that no one was subscribed because the partner was absent.
Why this matters
- Users waste time trying to fix audio when the real issue is a missing partner
- The
reportMissing button may be turned off in some studies (e.g., to avoid spamming all participants), so users have no other signal
- These events pollute Sentry's PE/PG issue groups, obscuring real device problems
- ~25% of pre-crash PE events in our analysis were this pattern
Proposed Implementation
1. Add subscription-aware diagnosis to FixAV
In the diagnosis flow (FixAV.jsx), check desiredSubscriptions before running device diagnostics. If all remote participants have {audio: false, video: false}, surface a different diagnosis:
// New diagnosis: check if any remote participants are subscribed
const hasSubscribedParticipant = [...desiredSubscriptions.entries()].some(
([_, tracks]) => tracks.audio || tracks.video
);
if (!hasSubscribedParticipant && remoteParticipantCount > 0) {
causes.push({
id: "noSubscribedParticipants",
description: "Your conversation partner hasn't joined the call yet",
fixDescription: "Wait for your partner or report them as missing",
fixable: false, // not auto-fixable
priority: 1, // highest priority — show this instead of device issues
});
// Skip device diagnostics — they're irrelevant without subscriptions
return causes;
}
2. Access desired subscriptions from FixAV
desiredSubscriptions is already stored in a module-level ref in Call.jsx (latestDesiredSubscriptions). Expose it to FixAV via the existing diagnostic data gathering:
// In FixAV's diagnostic data collection
desiredSubscriptions: Object.fromEntries(
[...(latestDesiredSubscriptions.current?.entries() || [])]
),
This ref is already used for FixAV error reporting (Call.jsx line 451), so the plumbing partially exists.
3. UI treatment
When noSubscribedParticipants is diagnosed:
- Show a clear message: "Your conversation partner hasn't joined the call yet"
- Offer guidance: "You can wait for them to join, or use the Report Missing button if available"
- Do NOT show device fix options (they're irrelevant)
- Still log to Sentry, but at
warning level instead of error, with the subscription state in extras
Test Plan
Add tests to playwright/component-tests/video-call/mocked/FixAV.ct.jsx:
FIXAV-NOSUB-001: Zero subscriptions diagnosed before device issues
- Mount VideoCall with multiple remote participants
- Set all desired subscriptions to
{audio: false, video: false}
- Trigger FixAV with "cant-hear" report
- Assert: diagnosis includes
noSubscribedParticipants
- Assert: diagnosis does NOT include
speakerNotSet (early return skips device checks)
FIXAV-NOSUB-002: Normal subscriptions proceed to device diagnosis
- Mount VideoCall with at least one participant subscribed
{audio: true, video: true}
- Trigger FixAV with "cant-hear" report
- Assert: diagnosis does NOT include
noSubscribedParticipants
- Assert: device diagnostics run normally
FIXAV-NOSUB-003: Zero remote participants skips subscription check
- Mount VideoCall with no remote participants (solo in room)
- Trigger FixAV with "cant-hear" report
- Assert: diagnosis does NOT include
noSubscribedParticipants (no one to subscribe to yet)
- Assert: device diagnostics run normally (problem may be that partner hasn't joined Daily at all)
FIXAV-NOSUB-004: Sentry capture uses warning level for no-subscription case
- Same setup as NOSUB-001
- Submit the FixAV report
- Assert: Sentry capture level is
warning, not error
- Assert: extras include
desiredSubscriptions state
Files to modify
client/src/call/FixAV.jsx — add subscription check to diagnosis flow
client/src/call/Call.jsx — expose latestDesiredSubscriptions to FixAV (may already be sufficient)
playwright/component-tests/video-call/mocked/FixAV.ct.jsx — add NOSUB tests
Related
Problem
When a participant's partner drops out of a video call, FixAV misdiagnoses the problem as a device issue (
speakerNotSet) rather than recognizing that no remote participants are subscribed. This sends users down a futile device-fix path instead of surfacing the actual problem: their partner isn't in the call.Evidence (Sentry event 83d27b6b, Feb 27)
A Listener in a 6-player storytelling study had their paired Storyteller drop out. The subscription system correctly set all 4 remaining remote participants to
{audio: false, video: false}(none were the partner). But when the user reported "cant-see, cant-hear":speakerNotSet(becausecallObject.getOutputDevices()returned null)speakerNotSetstill presentThe real problem was never audio devices — it was that no one was subscribed because the partner was absent.
Why this matters
reportMissingbutton may be turned off in some studies (e.g., to avoid spamming all participants), so users have no other signalProposed Implementation
1. Add subscription-aware diagnosis to FixAV
In the diagnosis flow (
FixAV.jsx), checkdesiredSubscriptionsbefore running device diagnostics. If all remote participants have{audio: false, video: false}, surface a different diagnosis:2. Access desired subscriptions from FixAV
desiredSubscriptionsis already stored in a module-level ref inCall.jsx(latestDesiredSubscriptions). Expose it to FixAV via the existing diagnostic data gathering:This ref is already used for FixAV error reporting (Call.jsx line 451), so the plumbing partially exists.
3. UI treatment
When
noSubscribedParticipantsis diagnosed:warninglevel instead oferror, with the subscription state in extrasTest Plan
Add tests to
playwright/component-tests/video-call/mocked/FixAV.ct.jsx:FIXAV-NOSUB-001: Zero subscriptions diagnosed before device issues
{audio: false, video: false}noSubscribedParticipantsspeakerNotSet(early return skips device checks)FIXAV-NOSUB-002: Normal subscriptions proceed to device diagnosis
{audio: true, video: true}noSubscribedParticipantsFIXAV-NOSUB-003: Zero remote participants skips subscription check
noSubscribedParticipants(no one to subscribe to yet)FIXAV-NOSUB-004: Sentry capture uses warning level for no-subscription case
warning, noterrordesiredSubscriptionsstateFiles to modify
client/src/call/FixAV.jsx— add subscription check to diagnosis flowclient/src/call/Call.jsx— exposelatestDesiredSubscriptionsto FixAV (may already be sufficient)playwright/component-tests/video-call/mocked/FixAV.ct.jsx— add NOSUB testsRelated
83d27b6ba4fa4bb4b10ea4dd13cb8c97ReportMissing.jsx) is the correct user path but may be disabled in some studies