plandex-ai/plandex · error

stream timeout due to inactivity: The AI model (%s/%s) is no

Error message

stream timeout due to inactivity: The AI model (%s/%s) is not responding

What it means

listenStream in tell_stream_main.go guards against a stalled LLM stream with a first-token/inactivity timer (sized by totalRequestTokens). If no chunk arrives from the model within the timeout and the stream hasn't finished, it raises 'stream timeout due to inactivity: The AI model (provider/model) is not responding' via state.onError with storeDesc=true and canRetry set only when zero output was received. This is a client-side watchdog, not a model error response.

Source

Thrown at app/server/model/plan/tell_stream_main.go:103

mainLoop:
	for {
		select {
		case <-active.Ctx.Done():
			// The main modelContext was canceled (not the timer)
			log.Println("\nTell: stream canceled")
			state.execHookOnStop(false)
			return
		case <-timer.C:
			// Timer triggered because no new chunk was received in time
			log.Println("\nTell: stream timeout due to inactivity")
			if streamFinished {
				log.Println("Tell stream finished—timed out waiting for usage chunk")
				state.execHookOnStop(false)
				return
			} else {
				res := state.onError(onErrorParams{
					streamErr: fmt.Errorf("stream timeout due to inactivity: The AI model (%s/%s) is not responding", modelProvider, modelName),
					storeDesc: true,
					canRetry:  active.CurrentReplyContent == "", // if there was no output yet, we can retry
				})

				if res.shouldReturn {
					return
				}
				if res.shouldContinueMainLoop {
					continue mainLoop
				}
			}

		case err := <-streamErrCh:
			log.Printf("listenStream - received from streamErrCh: %v\n", err)

			if err.Error() == "context canceled" {
				log.Println("Tell: stream context canceled")
				state.execHookOnStop(false)

View on GitHub (pinned to e2d772072e)

Solutions

  1. Retry the request (automatically allowed when no output was produced yet, canRetry=true)
  2. Check the named provider/model status — it is embedded in the message
  3. For local models, increase the first-token timeout or warm up the model before requests
  4. Verify network path/proxy isn't silently dropping idle connections

Example fix

// before
res := state.onError(onErrorParams{
    streamErr: fmt.Errorf("stream timeout due to inactivity: The AI model (%s/%s) is not responding", modelProvider, modelName),
    storeDesc: true,
    canRetry:  active.CurrentReplyContent == "",
})
// after
// warm up / health-check the model before long requests, and make timeout configurable
timeout := firstTokenTimeout(state.totalRequestTokens, baseModelConfig.LocalOnly)
log.Printf("listenStream: inactivity timeout %s for %s/%s", timeout, modelProvider, modelName)
res := state.onError(onErrorParams{
    streamErr: fmt.Errorf("stream timeout due to inactivity: The AI model (%s/%s) is not responding", modelProvider, modelName),
    storeDesc: true,
    canRetry:  active.CurrentReplyContent == "",
})
Defensive patterns

Strategy: retry

Validate before calling

if baseModelConfig.LocalOnly && !isLocalModelReady(provider, model) {
    return fmt.Errorf("local model %s/%s not ready; skipping request", provider, model)
}

Try / catch

case <-timer.C:
    res := state.onError(onErrorParams{
        streamErr: fmt.Errorf("stream timeout due to inactivity: The AI model (%s/%s) is not responding", modelProvider, modelName),
        storeDesc: true,
        canRetry:  active.CurrentReplyContent == "",
    })
    if res.shouldReturn {
        return
    }

Prevention

When it happens

Trigger: stream.Recv() blocks beyond firstTokenTimeout: provider hang, network black hole (no TCP reset), overloaded model backend, or a locally-hosted model that is still loading.

Common situations: Self-hosted/local model cold-start exceeding the timeout; provider outage or rate-limit stall; network middlebox silently dropping the connection; very large request causing long queue time.

Understand the failure class

Related errors


AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05). Data as JSON: /api/errors/34a984d57e31d420. Report an issue: GitHub.