plandex-ai/plandex · error
error updating plan active branches: %v
Error message
error updating plan active branches: %v
What it means
IncActiveBranches increments (or decrements, via a negative inc) plans.active_branches using the required *sqlx.Tx. This wrapper fires when that UPDATE fails. Since it always runs inside a transaction (called by CreateBranch and transactional anonymous blocks), the most common cause is executing against a transaction that was already aborted, or a connection failure during commit-heavy operations.
Source
Thrown at app/server/db/plan_helpers.go:293
var err error
if tx == nil {
_, err = Conn.Exec("UPDATE plans SET name = $1 WHERE id = $2", name, planId)
} else {
_, err = tx.Exec("UPDATE plans SET name = $1 WHERE id = $2", name, planId)
}
if err != nil {
return fmt.Errorf("error renaming plan: %v", err)
}
return nil
}
func IncActiveBranches(planId string, inc int, tx *sqlx.Tx) error {
_, err := tx.Exec("UPDATE plans SET active_branches = active_branches + $1 WHERE id = $2", inc, planId)
if err != nil {
return fmt.Errorf("error updating plan active branches: %v", err)
}
return nil
}
func IncNumNonDraftPlans(userId string, tx *sqlx.Tx) error {
_, err := tx.Exec("UPDATE users SET num_non_draft_plans = num_non_draft_plans + 1 WHERE id = $1", userId)
if err != nil {
return fmt.Errorf("error updating user num_non_draft_plans: %v", err)
}
return nil
}
func StoreDescription(description *ConvoMessageDescription) error {
descriptionsDir := getPlanDescriptionsDir(description.OrgId, description.PlanId)
View on GitHub (pinned to e2d772072e)
Solutions
- Ensure every error in the surrounding transaction triggers tx.Rollback() before any further statement — an aborted tx makes this UPDATE fail
- Check the inner error for connection issues; if the pool is exhausted, close transactions faster (avoid holding them across I/O)
- Verify inc values keep active_branches >= 0 if the column has a non-negative CHECK constraint
- Confirm the plans row for planId exists inside the tx before incrementing
Example fix
// before
_, err := tx.Exec("UPDATE plans SET active_branches = active_branches + $1 WHERE id = $2", inc, planId)
if err != nil {
return fmt.Errorf("error updating plan active branches: %v", err)
}
// after
_, err := tx.Exec("UPDATE plans SET active_branches = active_branches + $1 WHERE id = $2", inc, planId)
if err != nil {
tx.Rollback()
return fmt.Errorf("error updating plan active branches: %w", err)
} Defensive patterns
Strategy: try-catch
Validate before calling
var exists bool
if err := Conn.Get(&exists, "SELECT EXISTS(SELECT 1 FROM plans WHERE id = $1)", planId); err != nil || !exists {
return fmt.Errorf("plan %s not found", planId)
} Type guard
func txUsable(tx *sqlx.Tx) bool {
return tx != nil
} Try / catch
err := IncActiveBranches(planId, 1, tx)
if err != nil {
_ = tx.Rollback()
return fmt.Errorf("branch creation failed: %w", err)
}
if err := tx.Commit(); err != nil {
return fmt.Errorf("commit failed: %w", err)
} Prevention
- Roll back the transaction immediately on any error so subsequent statements never run on an aborted tx
- Do not hold transactions open across slow external I/O (avoids pool exhaustion and lock timeouts)
- Ensure inc values (positive or negative) keep active_branches valid under column constraints
- Keep the plan row's existence guaranteed within the same transaction that creates branches
When it happens
Trigger: Calling IncActiveBranches with an already-rolled-back or committed tx; DB connection failure inside the transaction; concurrent branch creation causing lock contention; constraint/trigger failure on the plans table during the increment.
Common situations: CreateBranch flows where a prior statement in the tx failed and the tx was not rolled back before this call; pool exhaustion while holding a tx open too long; passing a negative inc that drives active_branches negative when the column has a CHECK constraint.
Related errors
- error renaming plan: %v
- error updating plan total replies: %v
- error getting plan: %v
- error setting plan status: %v
- Error archiving plan:
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/6fdbf466e54592e2.
Report an issue: GitHub.