Cartesia (ja-JP): call ends before TTS audio finishes, final syllables clipped — same estimation issue as #3401, opposite direction

Related thread: Agent/caller speech mis-ordered in transcripts — caller answers after the agent finishes but is recorded as interrupting mid-sentence; breaks conversation-flow transitions (Japanese / Fish Audio TTS) — where Shah-Fazal identified the cause as “our transcript estimation is not designed for japanness character”.

We believe we are seeing the same Japanese estimation problem, but with a Cartesia voice it fails in the opposite direction, and it costs us audio rather than transcript accuracy: end_call fires while the TTS is still playing, so the caller never hears the end of the message. Same agent, same conversation flow, same message text — only the voice differs.

With Fish Audio (thread 3401), the estimate runs long: word timestamps land past the real audio, so caller replies look like mid-sentence interruptions. With Cartesia, the estimate runs short: Retell treats the utterance as finished early and the call is torn down mid-word.

These calls are from 2026-08-06 and 2026-08-07, after the fix mentioned in 3401, so if that fix shipped it does not cover the playout / end-call path.

ENVIRONMENT

Agent: agent_9fbf26727e8e36c3ad8e50298e (voiceai_stg_3d5a9af7), version 0, conversation flow, ja-JP, voice_speed 1.1.
Cartesia voice: custom_voice_40e9b59b6a413160becb57cd80 (sonic-3).
Fish Audio voice: custom_voice_c9cd94fd5a53bca14cc385c189 (s2-pro).

REPRODUCTION

Both calls end with the identical message: 「誠に恐れ入りますが、営業は終了いたしました。おかけ直しください。営業時間は9時から17時です。」

Cartesia — call_69d2de62b38a2e18a09a891db73

  • Recording length: 33.26s
  • Last word timestamp: 33.25s (matches the end of the audio exactly)
  • Silence after speech ends: 0.00s
  • Final 100ms of the recording: RMS 1698, i.e. still at full speech amplitude
  • What the caller hears: 「…9時から17時」 — the closing 「です」 never plays

Fish Audio — call_1d78212f739f0b92ca776625a3d

  • Recording length: 26.78s
  • Last word timestamp: 28.42s, i.e. 1.64s past the end of the audio (the symptom from thread 3401)
  • Silence after speech ends: 0.45s
  • Final 100ms of the recording: RMS 0
  • What the caller hears: the complete message

Both calls follow the identical path in public.log: shared_core-component_end → wrapper_end → Calling tool: end_call → Ending call. The transcript text is complete in both cases; only the Cartesia audio is lost.

Additional Cartesia examples on the same agent: call_81285a4ac65faaa976618cd002e (same message, clipped) and call_6b4c8760d2c2a0ff4d5d4a592ed (callback message clipped, with the following sentence bleeding into it).

EXPECTED

end_call should wait for the TTS stream to actually finish playing, rather than for an estimated duration — especially given that 3401 establishes the Japanese estimate as unreliable.

IMPACT

These are business-hours and callback announcements, the last thing a caller hears before hangup, so the clipped words are exactly the information the message exists to convey. We also use this Cartesia voice as the fallback_voice_ids entry for all of our Fish Audio voices, so a Fish Audio outage would put every one of our customers on the clipping path.

QUESTIONS

  1. Did the 3401 fix ship, and does it cover the playout / end_call path or only transcript timestamps?
  2. Does the Japanese estimation issue apply to Cartesia as well as Fish Audio?
  3. Is there a drain delay or grace period before end_call that we can set as a workaround?

Thanks,
Andrew

Hello @andrew3

I have escalated your issue to the relevant team.

Best Regards.

Hello @andrew3

We reproduced the pattern from the two calls and the mechanism is the mirror image of the Fish Audio case, as you suspected.

What we are seeing on the Cartesia leg:

On both affected turns, the trailing words of the final agent utterance carry a collapsed word timestamp (で / す / 。 pinned to ~33s on the Cartesia call, and the Fish call’s tail pinned to 28.4169s on its own call). Multiple words share one identical end time equal to the audio-render-end instant.

That collapse is what drives when end_call fires. Cartesia’s collapsed timestamps land essentially on top of the audio-render-end, so end_call is dispatched with almost no drain grace and the RTP tail to the caller is cut mid-syllable.

Fish Audio hides the same class of estimation gap in the opposite direction: its estimator overshoots real audio end by roughly 1.6 seconds, which is why the same script sounds complete there. It is not that Fish is doing the estimation correctly, it is that its overshoot gives accidental headroom before end_call runs.

The fix referenced in thread 3401 addressed transcript-side word estimation used for interruption detection (why Fish looked like the caller was interrupting). It did not cover the playout and end_call drain path, so this Cartesia-side symptom is consistent with that fix having shipped.

What can unblock you right now:

Add a short silence or wait node between the final message and end_call in the conversation flow, so the RTP tail drains regardless of when word alignment lands. A pause on the order of one to two seconds is usually enough to cover the worst-case Cartesia case.

Alternatively, shorten the final sentence before end_call, or move the goodbye content one turn earlier and let end_call fire after a short acknowledgement, which reduces the exposure to the collapsed-timestamp instant.

If you need a same-day workaround with no flow change, switching that agent’s voice to Fish Audio or ElevenLabs on the tail-critical calls avoids the Cartesia-specific alignment-close path.

Lowering Voice Speed from 1.1 back toward 1.0 also helps at the margin because slower audio gives Cartesia’s alignment stream more real time to deliver the last events before stream close.

Docs for reference:

Conversation flow nodes overview, including wait or silence style nodes:

Conversation flow agents: structured voice AI call control - Retell AI Voice configuration: Build overview: configure a Retell voice or chat agent .

Best Regards.

Hi Mark,

Thanks for the info. Are you planning a fix? When can we expect this to be fixed?

Andrew

Some additional call IDs, all ja-JP on Cartesia custom_voice_40e9b59b6a413160becb57cd80 (sonic-3). Every one of these was confirmed by listening, not by tooling.

Clipped on the transfer_call path — same sentence 「…営業時間内におかけなおしをお願いいたします。」, caller hears it end at 「お願い」, 「いたします。」 never plays. All three show 6 trailing tokens collapsed onto the render-end instant, then transfer_call dispatched ~50ms later:

call_e721dc2bf53f41c62f7989a5c7c turn 25.66-37.58s transfer_call at +43ms
call_a3acd4f9c8cf3d8d80f7da30597 turn 52.41-62.61s transfer_call at +57ms
call_180bc63124a1cd6c235c1b2feff turn 68.28-79.30s transfer_call at +69ms

That’s 3 of 3 sampled instances of this message, so it looks reproducible rather than intermittent. end_call is not involved in any of them — those calls end at 98.0s, 87.2s and 102.5s respectively. Will the fix cover the transfer_call dispatch path, or is drain grace being added per-handler?

Clipped with no dispatch at all:

call_90495493b02307ab79ad59321ee turn 27.31-35.30s no tool call, no node transition

4 trailing tokens 「ょうか?」 collapsed at 35.30s. public.log shows nothing between 33.30s and 38.30s; the caller answers at 37.36s and the call runs to 75.4s. Nothing was dispatched, so nothing cut the RTP tail, yet the closing 「でしょうか?」 is missing and the caller never hears that they were asked to confirm. Is this the same defect, or something separate on the render/playout side?

More examples. Two distinct shapes — in both, the transcript is complete and the audio is not.

Shape A — audio stops before the end of the transcript

call_81285a4ac65faaa976618cd002e
Transcript: 誠に恐れ入りますが、営業は終了いたしました。おかけ直しください。営業時間は9時から17時です。
Audio: stops after 「17時」. 「です。」 never plays. Call stays connected.

call_8ef25e37cdf6ee4f2e04e54e7f9
call_79205b8fe5521d1f626b4cea657
call_9642242f1ac1fb85536b5651d36
Transcript: …営業時間内におかけなおしをお願いいたします。
Audio: stops after 「お願い」. 「いたします。」 never plays.

Shape B — audio omits a span from the middle of the utterance and then resumes

This is the one not yet covered in this thread. Nothing is dispatched, and speech continues normally after the gap.

call_6b4c8760d2c2a0ff4d5d4a592ed
Transcript: …午前9時から17時**の間となります。**お電話番号は「ゼロ ゴー ゼロの…
Audio: stops after 「17時」, resumes at 「お電話番号は」. Compressed to ~25 ms per character across the gap.

call_788929971890643569f2cfc4749
call_b4ab10f9fc37c2509a2a421bd1d
call_7f98f9b310f2d82b1ee4f4b6291
Transcript: …プール利用の受付を休止**とさせていただきます。**最新情報は公式サイトのお知らせページをご確認くださいますようお願いいたします。
Audio: 「とさせていただきます」 — 2.8 s of transcript text — is never spoken. Audio continues normally from 「最新情報は」. Compressed to ~22 ms per character at 「最新情報は公式」.

Hello @andrew3

I have escalated your issue to the relevant team. As soon as I receive any updates from them, I will make sure to keep you informed.

Best Regards.

Hello @andrew3

Same sentence, three of three on transfer_call (call_e721dc2bf53f41c62f7989a5c7c, call_a3acd4f9c8cf3d8d80f7da30597, call_180bc63124a1cd6c235c1b2feff) Same class as the end_call case.The trailing tokens collapse onto audioTotalMs, and transfer_call is dispatched about 40 to 70ms later with no drain grace.

call_90495493b02307ab79ad59321ee, no dispatch This one is not the same defect. No tool ran between 33.30s and 38.30s and no node transition occurred, so nothing on our reducer path was in a position to cut the RTP tail.

Two candidate causes remain:

Cartesia’s HTTP synth actually returning less audio than the text implied for that closing token, or the collapsed transcript being a per-token estimator artifact rather than a real audio loss. One thing worth flagging: the collapse itself is not automatic proof of an audio cut on ja-JP Cartesia. Our per-word timing estimator on the HTTP path uses about 364ms per token at voice_speed 1.1, while a Japanese mora renders in roughly 130ms, so trailing tokens routinely spill past audioTotalMs and get pinned even when audio is complete.

Shape B, mid-utterance gap (call_6b4c8760d2c2a0ff4d5d4a592ed, call_788929971890643569f2cfc4749, call_b4ab10f9fc37c2509a2a421bd1d, call_7f98f9b310f2d82b1ee4f4b6291)

This is a separate defect, and it is not covered by the drain-grace change. There is no dispatch during the gap and speech resumes cleanly afterward. The compressed per-character interval you noticed at the resume point (about 22 to 25ms per character at 「最新情報は公式」) is our estimator racing to catch up after a real audio-byte gap, which means the bytes for the missing span were not delivered to the mixer.

Mitigations you can apply right now:

For the transfer_call and end_call tail cases, insert a short silence or wait node (about 1 to 2 seconds) between the final agent utterance and the tool call in the conversation flow. That covers both once and preserves the current voice.

For Shape B on long ja-JP static messages, splitting the message into two shorter agent turns at the observed break point (before 「最新情報は」 and before 「お電話番号は」) reliably avoids the drop while we investigate. Keeping any single ja-JP utterance under roughly one full sentence also helps.

If tail integrity is critical on a specific flow before the platform fixes land, switching that agent’s voice to Fish Audio or ElevenLabs on those tail-critical calls avoids both the Cartesia HTTP tail behavior and the mid-utterance drop.

We will also forward this to our engineering team to further investigate the root causes for this and potentially provide a fix.

Best Regards.

Hello @andrew3

Our engineering team has made a fix regarding this issue.

Best Regards.