plandex-ai/plandex · error

error updating plan total replies: %v

Error message

error updating plan total replies: %v

What it means

This error is produced inside the AddPlanConvoMessage helper's goroutine when the SQL UPDATE that increments a plan's total_replies counter fails. After an assistant message is stored, the code bumps total_replies on the plans row matching msg.PlanId; a database-level failure (connection issue, bad plan id, schema problem) surfaces here wrapped as 'error updating plan total replies'. The wrapped error is then re-wrapped by the caller's collector as 'error updating plan tokens'.

Source

Thrown at app/server/db/plan_helpers.go:179

		errCh <- nil
	}()

	go func() {
		defer func() {
			if r := recover(); r != nil {
				log.Printf("panic in AddPlanConvoMessage: %v\n%s", r, debug.Stack())
				errCh <- fmt.Errorf("panic in AddPlanConvoMessage: %v\n%s", r, debug.Stack())
				runtime.Goexit() // don't allow outer function to continue and double-send to channel
			}
		}()

		if msg.Role != openai.ChatMessageRoleAssistant {
			errCh <- nil
			return
		}
		_, err := Conn.Exec("UPDATE plans SET total_replies = total_replies + 1 WHERE id = $1", msg.PlanId)
		if err != nil {
			errCh <- fmt.Errorf("error updating plan total replies: %v", err)
		}

		errCh <- nil
	}()

	for i := 0; i < 2; i++ {
		err := <-errCh
		if err != nil {
			return fmt.Errorf("error updating plan tokens: %v", err)
		}
	}

	return nil
}

func SyncPlanTokens(orgId, planId, branch string) error {
	var contexts []*Context
	var convos []*ConvoMessage

View on GitHub (pinned to e2d772072e)

Solutions

  1. Check the inner error (the %v payload) for connection/refused errors and verify Postgres is reachable and the connection pool is configured for the request load
  2. Verify msg.PlanId references an existing plans row before calling AddPlanConvoMessage (e.g. via GetPlan)
  3. Confirm the plans table has the total_replies column (run the current migrations)
  4. Retry AddPlanConvoMessage; the counter increment is idempotent-unsafe so only retry once the message insert is confirmed not duplicated

Example fix

// before
_, err := Conn.Exec("UPDATE plans SET total_replies = total_replies + 1 WHERE id = $1", msg.PlanId)
if err != nil {
    errCh <- fmt.Errorf("error updating plan total replies: %v", err)
}
// after
var exists bool
if err := Conn.Get(&exists, "SELECT EXISTS(SELECT 1 FROM plans WHERE id = $1)", msg.PlanId); err == nil && exists {
    _, err := Conn.Exec("UPDATE plans SET total_replies = total_replies + 1 WHERE id = $1", msg.PlanId)
    if err != nil {
        errCh <- fmt.Errorf("error updating plan total replies: %v", err)
    }
}
errCh <- nil
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)", msg.PlanId); err != nil || !exists {
    return fmt.Errorf("plan %s does not exist", msg.PlanId)
}

Type guard

func planExists(planId string) bool {
    var exists bool
    _ = Conn.Get(&exists, "SELECT EXISTS(SELECT 1 FROM plans WHERE id = $1)", planId)
    return exists
}

Try / catch

if err := AddPlanConvoMessage(planId, msg); err != nil {
    log.Printf("plan token update failed for plan %s: %v", planId, err)
    // check errors.Is/sqlstate for transient errors and retry once
}

Prevention

When it happens

Trigger: An assistant-role ChatMessage is stored and `UPDATE plans SET total_replies = total_replies + 1 WHERE id = $1` returns an error: DB connection dropped/pool exhausted, msg.PlanId references a deleted plan, wrong planId format, or a table/column mismatch after migration.

Common situations: Postgres restart or connection timeout mid-stream; plan deleted concurrently while a reply is still streaming in; stale PlanId from client after branch/plan removal; migrations that renamed total_replies or the plans table.

Related errors


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