plandex-ai/plandex · error

Error getting branch:

Error message

Error getting branch: 

What it means

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.

Source

Thrown at app/server/handlers/plans_context.go:343

		return
	}

	vars := mux.Vars(r)
	planId := vars["planId"]
	branchName := vars["branch"]
	log.Println("planId: ", planId)

	plan := authorizePlan(w, planId, auth)

	if plan == nil {
		return
	}

	branch, err := db.GetDbBranch(planId, branchName)

	if err != nil {
		log.Printf("Error getting branch: %v\n", err)
		http.Error(w, "Error getting branch: "+err.Error(), http.StatusInternalServerError)
		return
	}

	// read the request body
	body, err := io.ReadAll(r.Body)
	if err != nil {
		log.Printf("Error reading request body: %v\n", err)
		http.Error(w, "Error reading request body", http.StatusInternalServerError)
		return
	}
	defer r.Body.Close()

	var requestBody shared.DeleteContextRequest
	if err := json.Unmarshal(body, &requestBody); err != nil {
		log.Printf("Error parsing request body: %v\n", err)
		http.Error(w, "Error parsing request body", http.StatusBadRequest)
		return
	}

View on GitHub (pinned to e2d772072e)

Solutions

  1. Verify the planId and branch path parameters exactly match an existing branch (list branches first)
  2. Check the underlying err text from GetDbBranch to distinguish not-found from a DB failure
  3. Re-select or recreate the branch if it was deleted concurrently
  4. Check DB connectivity/config if the error is a driver/connection error rather than not-found
  5. Consider mapping branch-not-found to 404 instead of 500

Example fix

// before
branch, err := db.GetDbBranch(planId, branchName)
if err != nil {
    http.Error(w, "Error getting branch: "+err.Error(), http.StatusInternalServerError)
}
// after
branch, err := db.GetDbBranch(planId, branchName)
if err != nil {
    if errors.Is(err, db.ErrBranchNotFound) {
        http.Error(w, "branch not found", http.StatusNotFound)
    } else {
        http.Error(w, "Error getting branch: "+err.Error(), http.StatusInternalServerError)
    }
}
Defensive patterns

Strategy: validation

Validate before calling

// before deleting, confirm the branch exists
branches, err := listBranches(planId)
if err != nil { return err }
if !containsBranch(branches, branchName) {
    return fmt.Errorf("branch %q does not exist on plan %s", branchName, planId)
}

Type guard

func branchExists(branches []Branch, name string) bool {
    for _, b := range branches { if b.Name == name { return true } }
    return false
}

Try / catch

resp, err := sendDelete(planId, branchName, ids)
if err != nil && resp != nil && resp.StatusCode == 500 {
    if strings.Contains(msg, "Error getting branch") {
        return fmt.Errorf("branch %q missing — refresh branch list", branchName)
    }
    return err
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05). Data as JSON: /api/errors/9df89cfe5c3f94db. Report an issue: GitHub.