{"record":{"id":"b86ac0b4ecdce0dc","repo":"plandex-ai/plandex","slug":"request-was-cancelled","errorCode":null,"errorMessage":"Request was cancelled","messagePattern":"Request was cancelled","errorType":"http","errorClass":null,"httpStatus":408,"severity":"info","filePath":"app/server/handlers/file_maps.go","lineNumber":82,"sourceCode":"\t\treturn\n\t}\n\n\tresults := make(chan shared.FileMapBodies, 1)\n\n\terr := queueProjectMapJob(projectMapJob{\n\t\tinputs:  req.MapInputs,\n\t\tctx:     r.Context(),\n\t\tresults: results,\n\t})\n\tif err != nil {\n\t\tlog.Println(\"GetFileMapHandler: map queue is full\")\n\t\thttp.Error(w, \"Too many project map jobs, please try again later\", http.StatusTooManyRequests)\n\t\treturn\n\t}\n\n\tselect {\n\tcase <-r.Context().Done():\n\t\thttp.Error(w, \"Request was cancelled\", http.StatusRequestTimeout)\n\t\treturn\n\tcase maps := <-results:\n\t\tif maps == nil {\n\t\t\thttp.Error(w, \"Mapping timed out\", http.StatusRequestTimeout)\n\t\t\treturn\n\t\t}\n\n\t\tresp := shared.GetFileMapResponse{\n\t\t\tMapBodies: maps,\n\t\t}\n\t\trespBytes, err := json.Marshal(resp)\n\t\tif err != nil {\n\t\t\thttp.Error(w, fmt.Sprintf(\"Error marshalling response: %v\", err), http.StatusInternalServerError)\n\t\t\treturn\n\t\t}\n\t\tw.Header().Set(\"Content-Type\", \"application/json\")\n\t\tw.Write(respBytes)\n","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/handlers/file_maps.go#L64-L100","documentation":"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.","triggerScenarios":"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().","commonSituations":"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.","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"],"exampleFix":"// before\nclient := &http.Client{} // default, no deadline control; LB times out at 30s\n// after\nclient := &http.Client{Timeout: 5 * time.Minute}\nresp, err := client.Post(mapURL, \"application/json\", body)","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Set a generous timeout and retry idempotent map requests\nclient := &http.Client{Timeout: 5 * time.Minute}\nfor attempt := 0; attempt < 3; attempt++ {\n    resp, err := client.Post(url, \"application/json\", body)\n    if err == nil && resp.StatusCode == http.StatusOK { break }\n}","preventionTips":["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"],"tags":["go","http","context","timeout","cancellation"],"backgroundTag":"request-context-cancelled","analyzedSha":"e2d772072efadbe41d2946d97d79be55532dbab5","analyzedAt":"2026-09-05T20:56:53.631Z","contentChangedAt":"2026-09-05T20:56:53.631Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}