plandex-ai/plandex · warning
timeout waiting for missing file choice
Error message
timeout waiting for missing file choice
What it means
Raised in handleMissingFile inside processChunk when the model asked the user to choose how to handle a missing file (prompt pushed to active.MissingFileResponseCh) and no answer arrived within 30 minutes. The processor intentionally uses a long timeout because it blocks on human input; on expiry it calls state.onError with storeDesc:true and stops processing (empty processChunkResult, hookOnStop already fired).
Source
Thrown at app/server/model/plan/tell_stream_processor.go:694
// log.Printf("Current reply content: %s\n", active.CurrentReplyContent)
// stop stream for now
active.CancelModelStreamFn()
log.Printf("Stopped stream for missing file: %s\n", currentFile)
// wait for user response to come in
var userChoice shared.RespondMissingFileChoice
select {
case <-active.Ctx.Done():
log.Println("Context cancelled while waiting for missing file response")
state.execHookOnStop(false)
return processChunkResult{shouldReturn: true}
case <-time.After(30 * time.Minute): // long timeout here since we're waiting for user input
log.Println("Timeout waiting for missing file choice")
state.onError(onErrorParams{
streamErr: fmt.Errorf("timeout waiting for missing file choice"),
storeDesc: true,
})
return processChunkResult{}
case userChoice = <-active.MissingFileResponseCh:
}
log.Printf("User choice for missing file: %s\n", userChoice)
active.ResetModelCtx()
UpdateActivePlan(planId, branch, func(ap *types.ActivePlan) {
ap.MissingFilePath = ""
ap.CurrentReplyContent = replyParser.GetReplyForMissingFile()
})
log.Println("Continuing stream")
View on GitHub (pinned to e2d772072e)
Solutions
- Answer the missing-file prompt (or re-send the user's choice into active.MissingFileResponseCh) within the 30-minute window.
- Increase the 30*time.After duration if longer human decision time is expected.
- Make the UI reliably surface the missing-file dialog so the user can respond.
- Detect client disconnect and cancel the wait early instead of blocking 30 minutes on a dead session.
- Re-run the request after the timeout — the stored error description marks the session as failed.
Example fix
// before
case <-time.After(30 * time.Minute):
log.Println("Timeout waiting for missing file choice")
// after: extend window and support cancellation on client disconnect
case <-time.After(2 * time.Hour):
state.onError(onErrorParams{streamErr: fmt.Errorf("timeout waiting for missing file choice"), storeDesc: true})
return processChunkResult{}
case <-active.ClientDisconnected:
state.execHookOnStop(false)
return processChunkResult{shouldReturn: true} Defensive patterns
Strategy: fallback
Validate before calling
// before blocking: ensure there is a live client able to answer the prompt
if active.MissingFileResponseCh == nil || !active.HasLiveClient() {
return processChunkResult{shouldReturn: true} // skip waiting entirely
} Type guard
func canAwaitUserChoice(active *StreamState) bool {
return active != nil && active.MissingFileResponseCh != nil && active.ClientConnected
} Try / catch
select {
case ch := <-active.MissingFileResponseCh:
// handle choice
case <-time.After(30 * time.Minute):
log.Println("Timeout waiting for missing file choice")
state.onError(onErrorParams{streamErr: fmt.Errorf("timeout waiting for missing file choice"), storeDesc: true})
return processChunkResult{}
} Prevention
- Always render the missing-file dialog promptly in the UI
- Auto-resolve with a sensible default (e.g. skip file) instead of blocking on humans
- Tie the wait to client-lifetime context cancellation, not only a timer
- Log when the prompt is issued so idle sessions can be detected early
When it happens
Trigger: The stream processor hit a missing-file prompt and waited on active.MissingFileResponseCh; the user never answered within 30 minutes (client closed, tab backgrounded, user walked away, or the UI never rendered the prompt).
Common situations: User leaves the session idle overnight after a missing-file prompt appears; client disconnects so the response channel is never written; a frontend bug swallows the missing-file dialog so nothing can send to MissingFileResponseCh; long-running agent session left unattended.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- connection to plan stream timed out due to missing heartbeat
- stream timed out due to inactivity. The model is not respond
- stream timeout due to inactivity: The AI model (%s/%s) is no
- context timeout
- refresh failed - http: %w
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/0cef91b4315222ef.
Report an issue: GitHub.