Troubleshooting: transcription, synthesis, and deepfake failures
This page owns the failure codes for every produce-then-read pipeline that turns speech into text or text into speech: the STT (speech-to-text) step, the TTS (text-to-speech) step, the voice and video transcript surfaces, the AI summary/eval steps running an LLM over those transcripts, and the synthetic-voice classifier on voice-biometrics enrollment. Each code tells you which stage broke, and the stage tells you who can fix it — the produce-side codes point at upstream provider health, the read-side codes point at a retry-safe surface failure. Readerror.code off the envelope; the matrix below maps each code to the
stage that raised it and to the section with the cause table, envelope
sample, and ticket checklist.
Code matrix — symptom to section
STT — upstream and codec
STT_TRANSCRIPTION_FAILED (500) means the speech-to-text provider either
did not answer or returned an unusable result, on the standalone
POST /api/v1/stt/transcribe surface or inside an agent pipeline turn.
Orbit routes STT through Deeway primary (the provider named in the
FAQ’s pipeline) with a failover chain the agent layer
re-orders per caller-requested language; a 500 on this surface fires only
when every leg came back empty or errored.
Codec matters here for standalone uploads: when the source call negotiates
a transcoding-heavy codec, the gateway funnels PCMU/PCMA frames through a
decode buffer before STT; a misalignment at that boundary produces
untranscribable audio rather than a provider failure. Confirm the negotiated
codec on the call — OPUS, PCMU (G.711 µ-law), or PCMA (G.711 A-law) are
the supported set per the FAQ codec list — and re-send a
clip in one of those before treating the failure as provider-side.
Cause table
Retry-safety
Safe to retry — a transcribe call writes nothing before the provider answers (the audio upload cap is enforced before the provider hop). Use exponential backoff over tens of seconds; a tight loop spends your rate limit against the same outage.Envelope sample
Ticket checklist
- The code (
STT_TRANSCRIPTION_FAILED) and the endpoint you called (/api/v1/stt/transcribe). - The codec the source call negotiated (OPUS / PCMU / PCMA) or the upload format you passed.
- Request IDs and timestamps for two or three failing calls — that brackets the provider window.
- Your organization ID (Settings → Organization, or
organizationIdfromGET /api/v1/me).
TTS — primary and fallback
TTS_SYNTHESIS_FAILED (500) fires on POST /api/v1/tts/synthesize (and
on the agent-turn path) when synthesis failed on every provider leg. The
FAQ’s STT → LLM → TTS pipeline routes TTS through
Cartesia as the primary provider; the agent pipeline falls to an
ElevenLabs leg when one is configured, with a per-leg timeout budget set
in milliseconds rather than a blocking wait. A 500 means both legs failed
or no fallback was configured.
Voice matters most here: the most common tenant-side cause is a
voice_id the provider rejects — a passed id that no longer exists on the
configured provider, or an agent whose saved voice config points at a
provider the organization has not activated. Retry once on the same id only
after re-reading the agent’s voice configuration; otherwise verify the
configured primary endpoint and the fallback leg before retrying again.
Cause table
Retry-safety
Safe to retry — synthesis writes nothing before the provider answers. The one non-retry case is the badvoice_id: a retry against the same
rejected id fails identically, so fix the voice config first.
Envelope sample
Ticket checklist
- The code (
TTS_SYNTHESIS_FAILED) and the endpoint (/api/v1/tts/synthesize, or the agent-turn path it rode on). - The voice id you passed (or
defaultwhen omitted). - Whether the failure is primary-leg-only or all-legs — the split decides between provider drift and chain exhaustion.
- Request IDs and timestamps for failing calls, plus your organization ID.
Transcript — not yet produced
All three codes here are 422 pre-check verdicts, not failures: the summary (or live-ask) service looked for a usable transcript, found none, and refused. That is distinct from the 5xx read/write failures in the next section — those are transient server-side faults you retry; a 422 here is a readiness state you resolve by waiting or by enabling capture.CALL_TRANSCRIPT_UNAVAILABLEfires onPOST /api/v1/voice/calls/:id/summarywhen the call has no usable transcript yet — typically because the recording→transcription producer has not finished, or transcription was disabled on the call.VIDEO_LIVE_TRANSCRIPT_UNAVAILABLEfires on the in-meeting live-assist endpoint (POST /api/v1/video/rooms-scheduled/:id/ask) when the room has captured no captions yet — captions off, or too little speech so far.VIDEO_TRANSCRIPT_UNAVAILABLEfires onPOST /api/v1/video/sessions/:id/summarywhen the meeting has no usable transcript — the meeting is still live, or closed captions were never enabled.
Cause table
For voice calls whose transcript never lands at all, check the
production side (recording/transcription enablement on the call flow)
before re-issuing the summary; for video, confirm the room had
captions/transcription enabled before the call.
Envelope sample
Ticket checklist
Only escalate when the transcript probe has been re-checked after the producer finished:- The code (one of the three above) and the endpoint.
- The call id / session_id / room id of the missing transcript.
- Whether captions or transcription were enabled on that call or room, and how long since it ended.
- Your organization ID.
Transcript reads and exports — retry-safe
The hosted video transcript surfaces read the captured record a meeting (or the correction write) produced. The three 5xx codes below mean that read/write hit a transient server fault — a tenant-schema blip, a DB pool exhaustion moment, or an export-pipeline race — and the request never partially applied anything. All three are safe to retry.VIDEO_TRANSCRIPT_LIST_FAILED(500) onGET /api/v1/video/rooms-scheduled/:id/transcripts— the paginated replay surface failed to load the transcript rows.VIDEO_TRANSCRIPT_EXPORT_FAILED(500) onGET /api/v1/video/rooms-scheduled/:id/transcripts/export— the caption-file export (WebVTT/SRT/digest) failed.VIDEO_TRANSCRIPT_CORRECT_FAILED(500) on the caption-correction surface (PATCH /api/v1/video/rooms-scheduled/:id/transcripts/:transcriptIdor the POST-correction variant on the same room) — the write failed.
LIST_FAILED, UNAVAILABLE) never
touches the write path (CORRECT_FAILED, EXPORT_FAILED).
Cause table
Envelope sample
Ticket checklist
- The code (one of the three above) and the endpoint.
- The room id you were reading (or the
transcriptIdon a correction write). - Whether every transcript surface fails or only one — the split separates a room-scoped condition from a surface-scoped one.
- Your organization ID.
DEEPFAKE_DETECTED — classifier, not consent
DEEPFAKE_DETECTED (422) is the synthetic-voice family classifier on the
voice-biometrics enrollment surfaces: the Resemble Detect synthetic-speech
score on the sample you submitted met or exceeded the platform threshold,
so the enrollment (or the clone-create request) refused. It is a classifier
verdict on the media you handed us — not a rights problem, not a consent
problem.
Distinguish it from the consent gates deliberately, because the two
families interact. The consent family
(AI voice consent guard,
FCC_AI_VOICE_WRITTEN_CONSENT_REQUIRED on the consent-check surfaces
before dial) is a recipient-consent record check — a written consent
record on the recipient must grant outbound synthetic voice content. The
deepfake classifier here is a media-authenticity check — the audio sample
itself was flagged as synthetic or cloned. Pasting a full-consent URL on
an enrollment the classifier refused still returns the same 422; the fix
is a genuine human-speech sample, not another consent record.
For the provenance side — how AI-generated output carries content
credentials so recipients and reviewers can check a provenance claim — see
Synthetic-media provenance. The
consent gates and the deepfake classifier both sit under the synthetic-voice
family umbrella, but this error carries only the classifier verdict: the
sample did not authenticate as human-performable speech. Allowed voice
clones enroll through the consent-registered speech
(create a voice clone) before any watermark or
synthesis runs, and the classifier applies to the enrollment sample itself.
Cause table
Retry-safety
Do not retry in a loop — every retry with the same flagged sample fails identically. Resolve the sample first, then re-submit once.Envelope sample
Ticket checklist
- The code (
DEEPFAKE_DETECTED) and the enrollment endpoint. - A short sample-description for the audio (recording method, speaker) — confirm it is a genuine human sample, not TTS.
- Whether the rejection happens on enrollment or on clone-create — the split separates classifier verdicts from clone-create pathing.
- Your organization ID. Consent gates are a separate family; only include a consent record reference if you have already verified it.
LLM summaries — malformed output
CALL_SUMMARY_LLM_MALFORMED (502) and VIDEO_SUMMARY_LLM_MALFORMED (502)
fire when the LLM endpoint answered, but its reply failed validation — the
summary service could not parse the expected JSON shape from the model
output, after retries at the service layer. The prompt was fine; the
model’s output was not.
Model drift under provider load is the usual cause, and the failure is
safe to retry: the request writes nothing before the summary is accepted,
and a retry rides the same transcript probe. A model endpoint that has
recovered answers the retry cleanly. When the retries you issued keep
returning the same 502, treat that window as a provider incident and
escalate — with the request IDs you captured, the recovery is minutes
rather than hours.
The follow-on watch item is the 503 sibling LLM_PROVIDER_UNCONFIGURED —
a deployment with no LLM key configured does not reach the malformed
stage; the summary surface raises the unconfigured code before any model
call. Escalate immediately there rather than retrying.
Cause table
Retry-safety
Safe to retry. Service-layer retries are exhausted before the 502 is surfaced, but a bounded manual backoff (three attempts over tens of seconds) is the right cadence; a tight loop spends your rate limit against the same malformed output.Envelope sample
Ticket checklist
- The code (
CALL_SUMMARY_LLM_MALFORMEDorVIDEO_SUMMARY_LLM_MALFORMED) and the endpoint. - Request IDs and timestamps for the failing calls — that brackets the provider window.
- The call id / session id you were summarizing.
- Your organization ID.
Do NOT retry these
- Do not retry
DEEPFAKE_DETECTEDin a loop. Every retry signs the same flagged sample over the classifier and fails identically; only a new genuine sample changes the verdict. - Do not submit longer samples to beat STT/TTS timeouts. A rejected
voice_idor an unsupported codec is deterministic — a retry with the same payload reads identically on every attempt. - Do not treat a 5xx transcript read as a transcript-absence verdict.
A
VIDEO_TRANSCRIPT_LIST_FAILEDorCORRECT_FAILED/EXPORT_FAILEDis a surface fault — retry it before you escalate; only the 422 family is a produce-side readiness verdict. - Do not re-synthesize the same
voice_id. A rejected voice id is deterministic; fix the agent’s voice config before re-issuing the call.
See also
- Error codes reference — the full catalog these codes live in, with HTTP status and retry-safety class.
- Frequently asked questions — the STT → LLM → TTS pipeline and the codec list on the voice lane.
- Synthetic-media provenance — how AI-generated voice and video output carries a tamper-evident credential.
- AI voice consent guard — the consent family the deepfake classifier is deliberately distinct from.
- Voice biometrics failures — the sibling sidecar connectivity and auth runbook on the same enrollment surfaces.
- Troubleshooting hub — the runbook index this page registers under.