← Back to PRs

#8297: fix(voice-call): prevent empty TwiML for non-in-progress outbound calls

by vishaltandale00 open 2026-02-03 21:21 View on GitHub →
channel: voice-call stale
Fixes #8276 ## Problem When initiating outbound voice calls, the Twilio webhook was returning empty TwiML: ```xml <?xml version="1.0" encoding="UTF-8"?><Response></Response> ``` This caused calls to fail immediately with Twilio error codes 11200 (HTTP retrieval failure), 15003 (media stream timeout), and 31951 (stream connection error). ## Root Cause The issue was in the `generateTwimlResponse` method in `twilio.ts` at lines 369-371. For outbound calls that weren't yet in "in-progress" status (e.g., "initiated" or "ringing"), the code would return `EMPTY_TWIML`, which Twilio interprets as an application error. ## Solution Removed the status check that was returning empty TwiML for non-in-progress calls. Now the webhook always attempts to generate appropriate TwiML: - Streaming TwiML (`<Connect><Stream>`) if media streaming is configured - PAUSE_TWIML as a fallback to keep the call alive This ensures outbound calls receive valid TwiML at all stages of the call lifecycle, whether in notify mode or conversation mode, with or without streaming configured. ## Testing This fix aligns with the existing test "returns streaming TwiML for outbound conversation calls before in-progress" which expects streaming TwiML even when call status is "initiated". 🤖 Generated with Claude Sonnet 4.5 <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This change adjusts Twilio webhook TwiML generation in `extensions/voice-call/src/providers/twilio.ts` to avoid returning empty `<Response/>` for outbound calls that aren’t yet `in-progress`. The previous `CallStatus !== "in-progress" => EMPTY_TWIML` guard was removed so outbound calls now receive either streaming TwiML (`<Connect><Stream .../>`) when a stream URL can be derived, or a `<Pause>` fallback to keep the call alive. This aligns behavior with existing outbound “initiated”/“ringing” expectations and prevents Twilio from treating the webhook response as an application error. <h3>Confidence Score: 4/5</h3> - This PR is likely safe to merge and fixes the reported empty-TwiML failure mode for outbound calls. - The diff is small and narrowly targets TwiML generation, matching the described root cause. Main residual concerns are behavioral broadening (non-inbound, non-status webhooks now get a Pause) and the possibility of repeated Pause polling if streaming can’t ever be established, but neither is an obvious regression for the primary call flow. - extensions/voice-call/src/providers/twilio.ts (TwiML branching behavior for unexpected webhook shapes). <!-- greptile_other_comments_section --> **Context used:** - Context from `dashboard` - CLAUDE.md ([source](https://app.greptile.com/review/custom-context?memory=fd949e91-5c3a-4ab5-90a1-cbe184fd6ce8)) - Context from `dashboard` - AGENTS.md ([source](https://app.greptile.com/review/custom-context?memory=0d0c8278-ef8e-4d6c-ab21-f5527e322f13)) <!-- /greptile_comment -->

Most Similar PRs