fix(voice-call): auto-end call on media stream disconnect#18435
Merged
steipete merged 4 commits intoopenclaw:mainfrom Feb 16, 2026
Merged
fix(voice-call): auto-end call on media stream disconnect#18435steipete merged 4 commits intoopenclaw:mainfrom
steipete merged 4 commits intoopenclaw:mainfrom
Conversation
When a Twilio media stream disconnects (e.g., caller hangs up or network drops), the call object was left in an active state indefinitely. This caused "stuck calls" that consumed resources and blocked new calls. Now calls are automatically ended when their media stream closes, matching the expected lifecycle behavior. Co-Authored-By: Claude Opus 4.6 <[email protected]>
extensions/voice-call/src/webhook.ts
Outdated
| const disconnectedCall = this.manager.getCallByProviderCallId(callId); | ||
| if (disconnectedCall) { | ||
| console.log(`[voice-call] Auto-ending call ${disconnectedCall.callId} on stream disconnect`); | ||
| void this.manager.endCall(disconnectedCall.callId).catch(() => {}); |
Contributor
There was a problem hiding this comment.
Silent error swallowing on endCall
The .catch(() => {}) silently discards all errors. While endCall is effectively idempotent (returns early for terminal states or missing calls), unexpected failures (e.g., network errors during the Twilio API call to complete the call) would be invisible. Other fire-and-forget patterns in this codebase log a warning on failure (e.g., events.ts:127-129, webhook.ts:124-126). Consider logging the error for observability:
Suggested change
| void this.manager.endCall(disconnectedCall.callId).catch(() => {}); | |
| void this.manager.endCall(disconnectedCall.callId).catch((err) => { | |
| console.warn(`[voice-call] Failed to auto-end call ${disconnectedCall.callId}:`, err); | |
| }); |
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/voice-call/src/webhook.ts
Line: 159:159
Comment:
**Silent error swallowing on endCall**
The `.catch(() => {})` silently discards all errors. While `endCall` is effectively idempotent (returns early for terminal states or missing calls), unexpected failures (e.g., network errors during the Twilio API call to complete the call) would be invisible. Other fire-and-forget patterns in this codebase log a warning on failure (e.g., `events.ts:127-129`, `webhook.ts:124-126`). Consider logging the error for observability:
```suggestion
void this.manager.endCall(disconnectedCall.callId).catch((err) => {
console.warn(`[voice-call] Failed to auto-end call ${disconnectedCall.callId}:`, err);
});
```
<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>
How can I resolve this? If you propose a fix, please make it concise.Co-Authored-By: Claude Opus 4.6 <[email protected]>
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Address review feedback: log a warning when endCall fails on stream disconnect instead of silently discarding the error. Co-Authored-By: Claude Opus 4.6 <[email protected]>
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
onDisconnectfires, matching expected lifecycleContext
Running OpenClaw with Twilio voice calls in a Docker deployment. When the media stream disconnects (common with network issues or normal hangup), the call record stays active. Over time, this accumulates stuck calls that must be manually cleared.
The fix adds
manager.endCall()in theonDisconnecthandler before unregistering the stream, so the call is properly cleaned up.Test plan
🤖 Generated with Claude Code
Greptile Summary
Adds automatic call cleanup when a Twilio media stream disconnects, preventing "stuck calls" that remain active indefinitely after the WebSocket closes (e.g., caller hangup, network drop). The fix inserts
manager.endCall()in theonDisconnecthandler before stream unregistration.endCallis idempotent — it returns early if the call is already in a terminal state or missing fromactiveCalls, and Twilio'shangupCallusesallowNotFound: truefor the REST API callcall.endedwebhook path are handled correctly — both paths converge on the sameendCallwhich guards against double cleanupunregisterCallStreamis correct —endCall/hangupCallcleans up auth tokens and webhook URLs, whileunregisterCallStreamcleans up the stream mapping with no overlap.catch(() => {})silently swallows errors, unlike similar fire-and-forget patterns elsewhere in this codebase that log warningsConfidence Score: 4/5
extensions/voice-call/src/webhook.ts) has a minor style suggestion but no functional issues.Last reviewed commit: c0cd3c2
(4/5) You can add custom instructions or style guidelines for the agent here!