{"record":{"id":"5a398ea6c76f96d0","repo":"plandex-ai/plandex","slug":"error-getting-plan-config","errorCode":null,"errorMessage":"Error getting plan config","messagePattern":"Error getting plan config","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"app/server/handlers/plan_config.go","lineNumber":37,"sourceCode":"\tauth := Authenticate(w, r, true)\n\tif auth == nil {\n\t\treturn\n\t}\n\n\tvars := mux.Vars(r)\n\tplanId := vars[\"planId\"]\n\n\tlog.Println(\"planId: \", planId)\n\n\tplan := authorizePlan(w, planId, auth)\n\tif plan == nil {\n\t\treturn\n\t}\n\n\tconfig, err := db.GetPlanConfig(planId)\n\tif err != nil {\n\t\tlog.Println(\"Error getting plan config: \", err)\n\t\thttp.Error(w, \"Error getting plan config\", http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\tres := shared.GetPlanConfigResponse{\n\t\tConfig: config,\n\t}\n\n\tbytes, err := json.Marshal(res)\n\tif err != nil {\n\t\tlog.Println(\"Error marshalling response: \", err)\n\t\thttp.Error(w, \"Error marshalling response\", http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\tw.Write(bytes)\n\tlog.Println(\"GetPlanConfigHandler processed successfully\")\n}\n","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/handlers/plan_config.go#L19-L55","documentation":"GetPlanConfigHandler returns HTTP 500 when db.GetPlanConfig(planId) errors after plan authorization succeeded. The handler deliberately returns a fixed message, hiding the underlying cause, so server logs are required to diagnose it.","triggerScenarios":"GET plan config where the plan_configs row for planId is missing/unreadable, the DB is unreachable, or the config data fails to scan (e.g. invalid JSON stored in the config column).","commonSituations":"Config row deleted manually, corrupt JSON in the stored config after a manual DB edit, schema drift after version upgrade, transient database outages.","solutions":["Check server logs for \"Error getting plan config: <err>\" to see the real cause","Run migrations to confirm the plan_configs table exists and matches the model","Fix or regenerate corrupt config rows (invalid JSON in the column)","Verify DB connectivity and retry after transient failures"],"exampleFix":"// before\nhttp.Error(w, \"Error getting plan config\", http.StatusInternalServerError)\n// after\nif errors.Is(err, sql.ErrNoRows) {\n    http.Error(w, \"Error getting plan config\", http.StatusNotFound)\n    return\n}\nhttp.Error(w, \"Error getting plan config\", http.StatusInternalServerError)","handlingStrategy":"retry","validationCode":"// client: only call for a plan you can access\nconst plan = await getPlan(planId);\nif (!plan) return; // 404/403 handled by authorizePlan before this error","typeGuard":null,"tryCatchPattern":"try {\n  const cfg = await getPlanConfig(planId);\n} catch (e) {\n  if (e.status === 500) { await backoffRetry(e, { attempts: 3 }); }\n  else throw e;\n}","preventionTips":["Treat missing config rows as empty defaults rather than errors","Run migrations on deploy","Log full underlying errors server-side (handler hides the cause)","Back up/validate stored config JSON"],"tags":["database","http-500","plan-config"],"backgroundTag":"database-query-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"}