ACP: a failed/unreachable-provider turn is reported as a successful session/prompt (stopReason: end_turn, no JSON-RPC error)
- Langage dominant
- Rust
- Étoiles
- 54.2k
- Forks
- 6.2k
- Merge moyen
- 3 j 2 h
- PR mergées (30 j)
- 262
Description
**Describe the bug**
Over ACP, when the configured provider is completely unreachable, `session/prompt` does not return a JSON-RPC error and `stopReason` does not indicate failure. The network failure is instead surfaced only as ordinary assistant text, and the request completes as `end_turn`. An automated ACP client cannot detect this failure from the JSON-RPC contract at all — it would have to pattern-match human-readable, locale-specific text in the streamed content.
---
**To Reproduce**
1. Configure `GOOSE_PROVIDER=ollama` with no Ollama daemon running (or otherwise make the configured provider fully unreachable).
2. Connect over ACP (`goose acp` over stdio), `initialize`, create a session, send `session/prompt` with a simple prompt.
3. Observe the exchange:
```
→ {"id":4,"method":"session/prompt","params":{"sessionId":"…","prompt":[{"type":"text","text":"Say hi"}]}}
← notif session/update {"sessionUpdate":"session_info_update","_meta":{"goose":{"activeRunId":"run_…"}}}
(logs: 10× "Request failed, retrying (n/10): NetworkError(\"Could not connect to localhost:11434…\")"
"Backing off for 2.2s / 5.1s / 11.2s / 17.7s … before retry")
← notif session/update {"sessionUpdate":"agent_message_chunk","content":{"type":"text",
"text":"Network error: Could not connect to localhost:11434 — check your network connection and try again.\n\nPlease resend your m…"}}
← notif session/update {"sessionUpdate":"session_info_update","_meta":{"goose":{"activeRunId":null}}}
← notif session/update {"sessionUpdate":"usage_update","used":0,"size":128000}
← {"id":4,"result":{"stopReason":"end_turn"}}
```
No JSON-RPC `error` object anywhere in the exchange; `result.stopReason` is `"end_turn"`, identical to a successful turn.
---
**Expected behavior**
Not prescribing a specific fix, but as options: a distinct `stopReason` (e.g. an error/refusal variant) or a structured error field on the response would let a programmatic ACP client distinguish "the model answered" from "the provider was unreachable and goose gave up" without string-matching assistant text.
---
**Please provide the following information**
- **OS & Arch:** Linux x86_64
- **Interface:** ACP (stdio), `goose acp`
- **Version:** `1.45.0-canary+eea5609` (`goose-x86_64-unknown-linux-musl`, `canary` release tag)
- **Extensions enabled:** none
- **Provider & Model:** Ollama, unreachable (`GOOSE_PROVIDER=ollama`, no daemon running)
---
**Additional context**
- The whole failure took **~105 seconds across ~10 retries**. This latency is already tracked for the Desktop UI in #10917 ("Connection-refused to a down local provider is retried for ~2 minutes before surfacing an error") and mid-stream transient errors in #10897 — both about the same retry/backoff mechanism (`crates/goose-provider-types/src/retry.rs`), so linking those for context rather than duplicating the latency complaint. This issue is specifically about the **JSON-RPC success/failure contract** over ACP, not the latency.
- We set `GOOSE_PROVIDER_SKIP_BACKOFF=1` to shorten the repro and it had no visible effect. Looking at `retry.rs`, `skip_backoff` is parsed with `std::env::var(...).parse::().unwrap_or(false)` — Rust's `bool::from_str` only accepts the literals `"true"`/`"false"` (case-sensitive), so `"1"` fails to parse and silently falls back to `false`. That's consistent with what we observed, though we haven't confirmed whether `"true"` behaves differently — flagging it as a likely explanation, not a verified fix.
- Tested **without real provider credentials** — Ollama was simply not running, purely to get past the "no provider configured" wall using a free/local provider. This means we only exercised the network-failure path; we did not verify what a genuinely successful ACP turn's `stopReason`/`result` looks like, only that this particular failure path is indistinguishable from one.
Guide de contribution
Ouvrir le guide de contribution
Évaluation
Cette issue n'a pas encore été évaluée.