Voice Agent Production Failure Checklist: 6 Bugs to Patch Before Going Live
Run your agent through these 6 checks before any client handoff, each with the exact fix, not just the problem.
Production Failure Checklist
6 checks remaining before client handoff.
Does every webhook that creates or modifies data include an idempotency key?
Fix
Pass a unique key (call_id + action_type) with every webhook call. The receiving endpoint checks for it and ignores duplicate requests, so platform retries on slow CRM responses don't create duplicate records.
Are appointment timestamps stored with a full IANA timezone string, not a UTC offset alone?
Fix
Store timestamps as ISO 8601 with an IANA name: e.g. 2026-10-27T15:00:00+01:00[Europe/Madrid]. The IANA name resolves the correct UTC offset after DST transitions. A bare UTC timestamp or offset like +01:00 doesn't.
Is every STT result gated on confidence before it reaches the LLM?
Fix
Three-tier handler: high confidence → normal LLM turn, mid → targeted clarification ('Did you say X?'), low → fallback offer (ask to repeat, then SMS link or transfer after two failures in a row).
Do all tool calls on the greeting path have a hard timeout (≤5 s) and a fallback utterance?
Fix
Set a 3 s timeout on real-time lookups, 5 s max on anything before the first greeting. If exceeded: emit a natural filler ('one moment…'), continue with a generic greeting, and log the failure. Never wait indefinitely.
Is structured input normalized programmatically before API calls, and is the response body verified, not just the HTTP status?
Fix
Normalize phone numbers to E.164 before every webhook call. After every CRM write, check the response body for a record ID or success flag. A 200 OK confirms the request was received. It does not confirm the write succeeded.
If the agent reads compliance content, does a state flag prevent the disclaimer from restarting when barge-in fires?
Fix
Track a DISCLAIMER_DELIVERED boolean in call state. While false: barge-in acknowledges the interruption but continues. It never restarts the disclaimer. Set to true when the full disclaimer finishes playing.