{"record":{"id":"331b786a5fb29b11","repo":"plandex-ai/plandex","slug":"error-getting-plan-convo","errorCode":null,"errorMessage":"Error getting plan convo: ","messagePattern":"Error getting plan convo: ","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"app/server/handlers/plans_convo.go","lineNumber":59,"sourceCode":"\t\tReason:   \"list convo\",\n\t\tScope:    db.LockScopeRead,\n\t\tCtx:      ctx,\n\t\tCancelFn: cancel,\n\t}, func(repo *db.GitRepo) error {\n\t\tres, err := db.GetPlanConvo(auth.OrgId, planId)\n\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tconvoMessages = res\n\n\t\treturn nil\n\t})\n\n\tif err != nil {\n\t\tlog.Println(\"Error getting plan convo: \", err)\n\t\thttp.Error(w, \"Error getting plan convo: \"+err.Error(), http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\tapiConvoMessages := make([]*shared.ConvoMessage, len(convoMessages))\n\tfor i, convoMessage := range convoMessages {\n\t\tapiConvoMessages[i] = convoMessage.ToApi()\n\t}\n\n\tbytes, err := json.Marshal(apiConvoMessages)\n\n\tif err != nil {\n\t\tlog.Println(\"Error marshalling plan convo: \", err)\n\t\thttp.Error(w, \"Error marshalling plan convo: \"+err.Error(), http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\tlog.Println(\"Successfully processed request for ListConvoHandler\")\n\tw.Write(bytes)","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/handlers/plans_convo.go#L41-L77","documentation":"ListConvoHandler returns this 500 when the ExecRepoOperation wrapping db.GetPlanConvo fails while loading a plan's conversation messages. The operation runs under a repo read lock, so failures include lock/context problems as well as storage read errors. The underlying error is appended to the response and logged.","triggerScenarios":"GET of a plan's convo where the repo operation fails: request context cancelled while waiting on the repo lock, plan branch/repo storage missing or corrupted, database read of convo messages fails, or the plan was deleted mid-request.","commonSituations":"Concurrent plan deletion or branch lock contention causing context cancellation; missing or unreadable plans storage directory/volume; Postgres read errors; stale planId from a deleted plan.","solutions":["Check the server log for the underlying GetPlanConvo/ExecRepoOperation error","Verify the planId and branch path params refer to an existing plan and branch","Check for lock contention or request-context cancellation from slow clients/proxies","Confirm the plans storage volume (git repo dir) and database are mounted and healthy"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"if (!planId || typeof planId !== 'string') throw new Error('planId required');\nconst plan = await getPlan(planId); // 404 here means convo lookup will also fail","typeGuard":null,"tryCatchPattern":"try {\n  const convo = await listPlanConvo(planId, branch);\n} catch (e) {\n  if (/Error getting plan convo/.test(e.message)) {\n    // transient lock/DB failure — retry with backoff\n    return withBackoff(() => listPlanConvo(planId, branch), 3);\n  }\n  throw e;\n}","preventionTips":["Keep request timeouts on proxies longer than expected repo-lock wait times","Refresh plan existence before long UI sessions that read convo","Retry idempotent GETs on 500 with exponential backoff","Alert on repeated 'Error getting plan convo' log lines"],"tags":["http-500","database","plans","conversation"],"backgroundTag":"database-read-failed","analyzedSha":"e2d772072efadbe41d2946d97d79be55532dbab5","analyzedAt":"2026-09-05T20:56:53.631Z","contentChangedAt":"2026-09-05T20:56:53.631Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}