Summary
When the provider accepts a request but never emits a first stream event, the session's visible outcome is the watchdog string Provider stream start timed out after <n>ms (optionally with the retry.provider.streamStartTimeoutMs hint). Same-model retries may run, but the turn does not fail over unless retry.fallbackChains has an explicit key for the current model. There is no shipped default chain. Start-time model-profile rungs are not used mid-session. The process stays up; this is not an uncaughtException crash.
Observed
- Assistant / error line:
Provider stream start timed out after 180000ms (bare prefix; current builds also append a setting hint).
- 180000 is not the shipped start default (300000, clamped to the idle timeout). It is an explicit
retry.provider.streamStartTimeoutMs or min(300000, idle) where idle is 180000 via httpIdleTimeoutMs or retry.provider.timeoutMs.
- No transparent switch to another model. Session remains on the failed turn.
Expected
- Process and session stay alive.
- Dead request is aborted at the stream-start bound; same-model retry spends the configured budget without shrinking that bound.
- If another model is available (configured
retry.fallbackChains or a later model-profile / category rung), switch to it and show the fallback notice. A successful fallback answer is the outcome.
- If nothing else can serve, show a recovery message: provider never started streaming, N attempts spent, configure
/fallback and/or raise retry.provider.streamStartTimeoutMs (0 disables). Do not leave the raw watchdog interpolation as the only visible line.
- Failed stall assistants must not remain the visible answer while retry or fallback continues.
Related
Notes for maintainers
Decision point: RetryFallbackController.nextCandidate returns undefined and logs no_chain when resolveChainKey finds no exact/base key. DEFAULT_FALLBACK_CHAINS is empty. TUI prints Error: ${message.errorMessage} for assistant stopReason: "error".
Summary
When the provider accepts a request but never emits a first stream event, the session's visible outcome is the watchdog string
Provider stream start timed out after <n>ms(optionally with theretry.provider.streamStartTimeoutMshint). Same-model retries may run, but the turn does not fail over unlessretry.fallbackChainshas an explicit key for the current model. There is no shipped default chain. Start-time model-profile rungs are not used mid-session. The process stays up; this is not an uncaughtException crash.Observed
Provider stream start timed out after 180000ms(bare prefix; current builds also append a setting hint).retry.provider.streamStartTimeoutMsormin(300000, idle)where idle is 180000 viahttpIdleTimeoutMsorretry.provider.timeoutMs.Expected
retry.fallbackChainsor a later model-profile / category rung), switch to it and show the fallback notice. A successful fallback answer is the outcome./fallbackand/or raiseretry.provider.streamStartTimeoutMs(0disables). Do not leave the raw watchdog interpolation as the only visible line.Related
no_chainfires).Notes for maintainers
Decision point:
RetryFallbackController.nextCandidatereturns undefined and logsno_chainwhenresolveChainKeyfinds no exact/base key.DEFAULT_FALLBACK_CHAINSis empty. TUI printsError: ${message.errorMessage}for assistantstopReason: "error".