{"record":{"id":"9df89cfe5c3f94db","repo":"plandex-ai/plandex","slug":"error-getting-branch","errorCode":null,"errorMessage":"Error getting branch: ","messagePattern":"Error getting branch: ","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"app/server/handlers/plans_context.go","lineNumber":343,"sourceCode":"\t\treturn\n\t}\n\n\tvars := mux.Vars(r)\n\tplanId := vars[\"planId\"]\n\tbranchName := vars[\"branch\"]\n\tlog.Println(\"planId: \", planId)\n\n\tplan := authorizePlan(w, planId, auth)\n\n\tif plan == nil {\n\t\treturn\n\t}\n\n\tbranch, err := db.GetDbBranch(planId, branchName)\n\n\tif err != nil {\n\t\tlog.Printf(\"Error getting branch: %v\\n\", err)\n\t\thttp.Error(w, \"Error getting branch: \"+err.Error(), http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\t// read the request body\n\tbody, err := io.ReadAll(r.Body)\n\tif err != nil {\n\t\tlog.Printf(\"Error reading request body: %v\\n\", err)\n\t\thttp.Error(w, \"Error reading request body\", http.StatusInternalServerError)\n\t\treturn\n\t}\n\tdefer r.Body.Close()\n\n\tvar requestBody shared.DeleteContextRequest\n\tif err := json.Unmarshal(body, &requestBody); err != nil {\n\t\tlog.Printf(\"Error parsing request body: %v\\n\", err)\n\t\thttp.Error(w, \"Error parsing request body\", http.StatusBadRequest)\n\t\treturn\n\t}","sourceCodeStart":325,"sourceCodeEnd":361,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/handlers/plans_context.go#L325-L361","documentation":"DeleteContextHandler calls db.GetDbBranch(planId, branchName) to look up the target branch before deleting contexts; that call returned an error, so the handler responds with HTTP 500. The error usually means the branch row does not exist for that planId/branch pair or the DB lookup itself failed — notably, a missing branch surfaces here as 500 rather than 404.","triggerScenarios":"Calling the delete-contexts endpoint with a planId/branch path pair that has no DB branch row (typo'd, stale, URL-encoded, or concurrently deleted branch), or an underlying DB/driver error during the lookup.","commonSituations":"A client caches a branch another user deleted; wrong case in the branch path variable; DB outage or misconfigured connection string; migration drift so the branches table is missing rows.","solutions":["Verify the planId and branch path parameters exactly match an existing branch (list branches first)","Check the underlying err text from GetDbBranch to distinguish not-found from a DB failure","Re-select or recreate the branch if it was deleted concurrently","Check DB connectivity/config if the error is a driver/connection error rather than not-found","Consider mapping branch-not-found to 404 instead of 500"],"exampleFix":"// before\nbranch, err := db.GetDbBranch(planId, branchName)\nif err != nil {\n    http.Error(w, \"Error getting branch: \"+err.Error(), http.StatusInternalServerError)\n}\n// after\nbranch, err := db.GetDbBranch(planId, branchName)\nif err != nil {\n    if errors.Is(err, db.ErrBranchNotFound) {\n        http.Error(w, \"branch not found\", http.StatusNotFound)\n    } else {\n        http.Error(w, \"Error getting branch: \"+err.Error(), http.StatusInternalServerError)\n    }\n}","handlingStrategy":"validation","validationCode":"// before deleting, confirm the branch exists\nbranches, err := listBranches(planId)\nif err != nil { return err }\nif !containsBranch(branches, branchName) {\n    return fmt.Errorf(\"branch %q does not exist on plan %s\", branchName, planId)\n}","typeGuard":"func branchExists(branches []Branch, name string) bool {\n    for _, b := range branches { if b.Name == name { return true } }\n    return false\n}","tryCatchPattern":"resp, err := sendDelete(planId, branchName, ids)\nif err != nil && resp != nil && resp.StatusCode == 500 {\n    if strings.Contains(msg, \"Error getting branch\") {\n        return fmt.Errorf(\"branch %q missing — refresh branch list\", branchName)\n    }\n    return err\n}","preventionTips":["Always re-list branches before deleting; never use cached branch names","Handle URL-encoding of branch names in path parameters","Expect not-found to surface as 500 today; treat 'Error getting branch' as 404 semantics","Watch for concurrent deletions by other users in shared plans"],"tags":["http","go","database","branch","server"],"backgroundTag":"branch-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"}