# The AI provider refused

Four unrelated conditions look identical from a screen: the account is out of quota, the key is rejected, the spend ceiling was reached, or the configured model is not a valid choice for what was asked. Two of them open a provider breaker, one is local arithmetic that never touches the provider, and one is a configuration mistake reported before anything starts.

- **Status:** Available
- **Audience:** both
- **In the app:** #/calls, #/activity
- **Last verified:** 2026-09-10
- **Canonical:** https://connectbyjbrh.com/docs/troubleshooting/model-unavailable/

## What the symptom looks like

Work that needs a model stops producing anything. Drafts are not written, scheduled thinking does nothing, and on the phone a call either does not go out or an inbound caller hears the closed-line message rather than a conversation. Nothing else on the product is affected, because everything that is stored is still readable.

The four causes are worth separating before acting, because two of them resolve on their own within minutes, one needs a decision about spending, and one needs a configuration change that no amount of waiting will make.

## Telling the four apart

| Cause | Where it is decided | The distinguishing test | How it clears |
|---|---|---|---|
| Out of quota | At the provider | Scheduled work is skipped while anything you do by hand is still attempted | The first successful call, or the breaker window elapsing |
| Key rejected | At the provider | Foreground attempts fail too, immediately and consistently | A working key; the breaker then closes on the next success |
| Spend ceiling reached | Locally, before the provider is called | The provider is healthy and would have answered | Raising the ceiling, or the period turning over |
| Model not a valid choice | Locally, before a session opens | The refusal names the model rather than an account | Choosing a model that supports what was asked |

> **Note** Quota and a rejected key are grouped on purpose. From the caller's side they behave identically — both fail every time, both fail for reasons no retry improves — so both open the same breaker rather than being distinguished by an optimism neither deserves.

## What Connect completed

- Everything that did not need a model carried on: mail was fetched, stored, made canonical and indexed; screens, search and the grid answered normally.
- The refusal itself was recorded with its reason, and open breakers appear in the health summary rather than only in a log.
- On the phone, a refused inbound call was still answered, still given the closed-line message in the business's voice, and still recorded as a call with an outcome.
- Work that could not run was left where it was, due and unstarted, rather than being marked done or failed.

## What Connect did not complete

- No reply was drafted, so nothing is waiting in a half-written state.
- No scheduled thinking ran for the affected period. It was skipped, not queued a thousand times over.
- No model call was retried into an account that had already refused — the loop this behaviour replaced ran for four weeks against an account that was never going to answer.
- No fallback model was substituted quietly. A model that cannot do what was asked is reported, not swapped for one whose answers would be different without anybody being told.

## What you can do

1. Try one thing by hand — ask the Assistant a question, or open a draft.
   - Result: If foreground work succeeds while scheduled work is skipped, it is a breaker inside its window and it closes on its own.
2. If foreground work fails too, the account or the key is the problem, and it is fixed at the provider.
   - Result: The breaker closes on the first call that gets through; there is nothing to reset here.
3. If the provider is healthy, look at the spend ceiling rather than the account.
   - Result: A local refusal names a budget, not a provider, and no amount of provider fiddling changes it.
4. If the message names a model, change the model choice.
   - Result: This one never resolves by waiting, and the refusal is deliberately raised before a session opens rather than surfacing as a failed call.

## What an administrator can do, and when to escalate

An administrator can resolve the account at the provider, adjust the spend ceiling deliberately, or change the configured model. Each is a different decision with a different cost, which is why the four causes are worth separating before anybody starts changing settings — changing a model to work around an empty account produces a working system with different behaviour and an unresolved bill.

Escalate when foreground and background work both succeed intermittently with no breaker open and no ceiling reached. That pattern is neither of the four and is worth reporting with the times of a successful and a failed attempt — not with raw provider text, which carries identifiers that do not belong in a support thread.

## Questions

### Why does the Assistant still work when scheduled work has stopped?

Because a person is waiting on it. Work somebody is waiting for is attempted even while a breaker is open; scheduled work asks first and is skipped. The asymmetry is deliberate and is usually the fastest way to identify a breaker.

### Does the spend ceiling stop a call that has already connected?

No. The check happens before a call starts, at both ends — before an outbound call is placed and before an inbound one is answered. A call already running is bounded by its configured session cap instead.

### Can Connect fall back to a different model automatically?

It does not substitute one silently. A model that cannot support what was asked is refused with the model named, because quietly changing which model answers changes the answers, and a person should be the one deciding that.

## Related

- [A provider quota breaker opening and closing](https://connectbyjbrh.com/docs/workflows/quota-breaker/)
- [The AI budget is spent](https://connectbyjbrh.com/docs/troubleshooting/budget-exhausted/)
- [The AI budget guard, end to end](https://connectbyjbrh.com/docs/workflows/budget-guard/)
- [What a setting cannot change](https://connectbyjbrh.com/docs/phone/model-limits/)
- [The voice model refused the session](https://connectbyjbrh.com/docs/troubleshooting/model-session-failed/)
- [A provider is down](https://connectbyjbrh.com/docs/troubleshooting/provider-outage/)

## What this page is based on

- `backend/app/ai_quota.py` — classification, the breaker, foreground and background
- `backend/app/voice_engine.py` — the budget refusal and the model check before a call
- docs-source/sources/PHONE.md §4 — what stops a call
- Connect capability registry (docs-source/facts.py)
