Calls that were never a conversation
Three different nothings share one word in Connect: NOT_A_CONVERSATION. no_answer rang and nobody picked up. not_reached never rang at all — the dial, the dispatch or the worker failed. A silent failure is worse than both: the call connected and nothing could be said. None of the three creates a lead.
Telling them apart#
no_answer | not_reached | Silent failure | |
|---|---|---|---|
| Did it ring? | Yes | No | Yes — and it was answered |
| Did anyone speak? | No | No | No, though both parties were connected |
| Whose problem is it? | The person being called, or the list | The dial, the dispatch or the worker | Connect's |
| How it looks in the record | A short call with no turns | A call that never reached a ringing state | Historically: "the caller hung up before speaking" |
| What to do | Nothing, or call at a better hour | Check line health and worker capacity | Check the greeting path and the model |
The middle column is the one that escalates by itself. Past HEALTH_MIN_FAILURES inside HEALTH_WINDOW_HOURS, a run of calls that never rang becomes a line-health finding in Needs You, because a line failing to reach anybody is an operational fault rather than a bad day on the phones.
The silent one#
A silent failure is a call the caller answered, held to their ear, and heard nothing from. It has a specific cause with a specific record: when the greeting cannot be said — the synthesis is refused and the model in use takes no generated line — the worker posts engine_error {at: greeting} and ends the call with hangup_by=engine rather than leaving somebody listening to silence.
The engine then writes facts.silent_failure from that event, and voice.no_conversation says so, with outcome not_reached. Before that chain existed, five inbound calls on 2026-09-07 sat silent and were recorded as "the caller hung up before speaking" — a row that is entirely plausible, contains no error, and is false.
Why none of them creates a lead#
_capture_lead creates nothing from a call that was never a conversation. The reasoning is the same as the summariser's floor: a lead is a claim that somebody is interested, and there is no evidence of interest in a phone ringing out. A pipeline fed by dialling volume measures effort and presents it as demand.
The same holds for memory and facts. Nothing is remembered about a person from a call in which they said nothing, so a run of unanswered attempts does not gradually build a profile out of its own failures.
- What is created
- A
Callrow with the outcome, the attempt, the cost and the attribution. The attempt is on the record. - What is not created
- A lead, a summary, a fact, a memory or a person, unless one already existed.
- What happens to the follow-up
- It is not completed by a call nobody answered. A phone follow-up that could not be placed is retried; one more than 24 hours late is closed as
missed:.
Reducing them#
Split your failures by outcome before changing anything.
Result You know whether you are looking at a calling problem or an engineering one, which are fixed in different places.
For
not_reached, check whether a worker had checked in and whether the fleet had capacity.Result Admission refuses
not_readybefore a row exists when no worker has checked in for 90 seconds, precisely so the drain can retry rather than burn the follow-up.For silent failures, check whether the greeting was warmed or synthesised live, and whether the model in use accepts a generated line.
Result A greeting that cannot be spoken at all now ends the call deliberately — visible as
engine, not as the caller.For
no_answer, look at when you are calling rather than at the stack.Result The line's hours and the promised time from the call are both in the record, and one of them is usually wrong.
Questions#
Does an unanswered call cost anything?
It is metered like any other call. A call that reports no model usage is charged from its own duration at the published per-minute rate, so an unanswered attempt is cheap rather than free — which is the honest way for a large outbound list to appear in a ledger.
Can I make Connect retry a call nobody answered?
A follow-up is the mechanism, not a retry loop inside the call. The promise stays due, the drain attempts it on the next tick within the line's hours, and a promise more than a day late is closed rather than kept — a very late call-back is treated as worse than none.
How do I know a silent failure happened rather than a caller who really did hang up?
Look for engine_error at the greeting and for facts.silent_failure on the call. A genuine early hang-up leaves the greeting event showing that the greeting was said. If both are absent on an old row, treat the attribution as uncertain — the vocabulary that distinguishes them is newer than the row.