plandex-ai/plandex · info
Request was cancelled
Error message
Request was cancelled
What it means
After enqueueing the job, GetFileMapHandler waits on a select over r.Context().Done() and the results channel. If the client's request context is cancelled (client disconnect, timeout, or shutdown), it responds HTTP 408 with 'Request was cancelled'. Mapping work is abandoned server-side.
Source
Thrown at app/server/handlers/file_maps.go:82
return
}
results := make(chan shared.FileMapBodies, 1)
err := queueProjectMapJob(projectMapJob{
inputs: req.MapInputs,
ctx: r.Context(),
results: results,
})
if err != nil {
log.Println("GetFileMapHandler: map queue is full")
http.Error(w, "Too many project map jobs, please try again later", http.StatusTooManyRequests)
return
}
select {
case <-r.Context().Done():
http.Error(w, "Request was cancelled", http.StatusRequestTimeout)
return
case maps := <-results:
if maps == nil {
http.Error(w, "Mapping timed out", http.StatusRequestTimeout)
return
}
resp := shared.GetFileMapResponse{
MapBodies: maps,
}
respBytes, err := json.Marshal(resp)
if err != nil {
http.Error(w, fmt.Sprintf("Error marshalling response: %v", err), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
w.Write(respBytes)
View on GitHub (pinned to e2d772072e)
Solutions
- Increase the client's HTTP request timeout beyond the expected mapping duration for the batch size
- Reduce batch size (<=10MB / 500 files) so mapping completes well inside timeouts
- Avoid cancelling/retrying immediately; let in-flight requests finish before issuing retries
- Check/raise any proxy or load-balancer idle timeout in front of the server
Example fix
// before
client := &http.Client{} // default, no deadline control; LB times out at 30s
// after
client := &http.Client{Timeout: 5 * time.Minute}
resp, err := client.Post(mapURL, "application/json", body) Defensive patterns
Strategy: retry
Try / catch
// Set a generous timeout and retry idempotent map requests
client := &http.Client{Timeout: 5 * time.Minute}
for attempt := 0; attempt < 3; attempt++ {
resp, err := client.Post(url, "application/json", body)
if err == nil && resp.StatusCode == http.StatusOK { break }
} Prevention
- Set client timeouts well above expected mapping duration
- Raise LB/proxy idle timeouts for this endpoint
- Keep batches small to finish before any timeout
- Don't cancel and immediately retry; drain or reuse connections
When it happens
Trigger: The HTTP client closes the connection or its deadline expires while the server is still computing the file map; server graceful shutdown cancels r.Context().
Common situations: Client-side HTTP timeouts shorter than mapping time for big batches; user aborts a request; load balancer idle timeouts (often 30–60s) cutting long mappings; retry storms that abandon in-flight requests.
Related errors
- connection to plan stream timed out due to missing heartbeat
- context timeout
- token exchange failed - error creating request: %s
- token exchange failed - error reading body: %s
- token exchange failed - status: %d, body: %s
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/b86ac0b4ecdce0dc.
Report an issue: GitHub.