{"record":{"id":"47651a26226def07","repo":"plandex-ai/plandex","slug":"error-getting-plan-config-v-47651a","errorCode":null,"errorMessage":"error getting plan config: %v","messagePattern":"error getting plan config: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/server/db/plan_config_helpers.go","lineNumber":18,"sourceCode":"package db\n\nimport (\n\t\"fmt\"\n\n\tshared \"plandex-shared\"\n\n\t\"github.com/jmoiron/sqlx\"\n)\n\nfunc GetPlanConfig(planId string) (*shared.PlanConfig, error) {\n\tquery := \"SELECT plan_config FROM plans WHERE id = $1\"\n\n\tvar config shared.PlanConfig\n\terr := Conn.Get(&config, query, planId)\n\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error getting plan config: %v\", err)\n\t}\n\n\treturn &config, nil\n}\n\nfunc StorePlanConfig(planId string, config *shared.PlanConfig) error {\n\tquery := `\n\t\tUPDATE plans \n\t\tSET plan_config = $1\n\t\tWHERE id = $2\n\t`\n\n\t_, err := Conn.Exec(query, config, planId)\n\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error storing plan config: %v\", err)\n\t}\n","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/db/plan_config_helpers.go#L1-L36","documentation":"GetPlanConfig wraps a failure of Conn.Get(&config, \"SELECT plan_config FROM plans WHERE id = $1\", planId) with this message. Because sqlx Get requires exactly one row, this error fires both for a nonexistent planId (sql.ErrNoRows) and for genuine query/scan failures.","triggerScenarios":"LoadContexts/UpdateContexts/GetPlanConfigHandler pass a planId that doesn't exist in plans (most common: sql: no rows in result set), the DB is unreachable, or plan_config cannot be scanned into shared.PlanConfig (malformed JSON in the column).","commonSituations":"Client references a deleted plan; stale plan id cached in the UI; plan row deleted mid-session; database migrated so plan_config column type changed; corrupted JSONB value.","solutions":["Read the wrapped cause: 'sql: no rows in result set' means the planId doesn't exist — verify the plan exists before loading and return 404 to the client","Check that the plan belongs to the caller's org/project if the id comes from user input","If the cause is a scan/JSON error, inspect the plans.plan_config value for corruption and fix the data","For connection errors, verify DATABASE_URL and Postgres health, then retry"],"exampleFix":"// before\nconfig, err := GetPlanConfig(planId)\n// after: distinguish not-found from real failures\nconfig, err := GetPlanConfig(planId)\nif err != nil {\n    if strings.Contains(err.Error(), \"no rows in result set\") {\n        http.Error(w, \"plan not found\", http.StatusNotFound)\n        return\n    }\n    http.Error(w, \"internal error\", http.StatusInternalServerError)\n    return\n}","handlingStrategy":"try-catch","validationCode":"var exists bool\nerr := Conn.Get(&exists, \"SELECT EXISTS(SELECT 1 FROM plans WHERE id=$1)\", planId)\nif err != nil || !exists {\n    // return 404 before calling GetPlanConfig\n}","typeGuard":null,"tryCatchPattern":"config, err := GetPlanConfig(planId)\nif err != nil {\n    if strings.Contains(err.Error(), \"no rows in result set\") {\n        http.Error(w, \"plan not found\", http.StatusNotFound)\n        return\n    }\n    log.Printf(\"GetPlanConfig: %v\", err)\n    http.Error(w, \"internal error\", http.StatusInternalServerError)\n    return\n}","preventionTips":["Treat 'no rows in result set' as not-found, not a crash","Validate planId format (uuid) and ownership before lookup","Never hard-delete plans; soft-delete so configs remain loadable","Ensure plan_config JSONB values stay valid JSON (constrain writes)"],"tags":["database","postgres","not-found","sqlx","go"],"backgroundTag":"record-not-found","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"}