plandex-ai/plandex · error

Error getting plan convo:

Error message

Error getting plan convo: 

What it means

ListConvoHandler returns this 500 when the ExecRepoOperation wrapping db.GetPlanConvo fails while loading a plan's conversation messages. The operation runs under a repo read lock, so failures include lock/context problems as well as storage read errors. The underlying error is appended to the response and logged.

Source

Thrown at app/server/handlers/plans_convo.go:59

		Reason:   "list convo",
		Scope:    db.LockScopeRead,
		Ctx:      ctx,
		CancelFn: cancel,
	}, func(repo *db.GitRepo) error {
		res, err := db.GetPlanConvo(auth.OrgId, planId)

		if err != nil {
			return err
		}

		convoMessages = res

		return nil
	})

	if err != nil {
		log.Println("Error getting plan convo: ", err)
		http.Error(w, "Error getting plan convo: "+err.Error(), http.StatusInternalServerError)
		return
	}

	apiConvoMessages := make([]*shared.ConvoMessage, len(convoMessages))
	for i, convoMessage := range convoMessages {
		apiConvoMessages[i] = convoMessage.ToApi()
	}

	bytes, err := json.Marshal(apiConvoMessages)

	if err != nil {
		log.Println("Error marshalling plan convo: ", err)
		http.Error(w, "Error marshalling plan convo: "+err.Error(), http.StatusInternalServerError)
		return
	}

	log.Println("Successfully processed request for ListConvoHandler")
	w.Write(bytes)

View on GitHub (pinned to e2d772072e)

Solutions

  1. Check the server log for the underlying GetPlanConvo/ExecRepoOperation error
  2. Verify the planId and branch path params refer to an existing plan and branch
  3. Check for lock contention or request-context cancellation from slow clients/proxies
  4. Confirm the plans storage volume (git repo dir) and database are mounted and healthy
Defensive patterns

Strategy: retry

Validate before calling

if (!planId || typeof planId !== 'string') throw new Error('planId required');
const plan = await getPlan(planId); // 404 here means convo lookup will also fail

Try / catch

try {
  const convo = await listPlanConvo(planId, branch);
} catch (e) {
  if (/Error getting plan convo/.test(e.message)) {
    // transient lock/DB failure — retry with backoff
    return withBackoff(() => listPlanConvo(planId, branch), 3);
  }
  throw e;
}

Prevention

When it happens

Trigger: GET of a plan's convo where the repo operation fails: request context cancelled while waiting on the repo lock, plan branch/repo storage missing or corrupted, database read of convo messages fails, or the plan was deleted mid-request.

Common situations: Concurrent plan deletion or branch lock contention causing context cancellation; missing or unreadable plans storage directory/volume; Postgres read errors; stale planId from a deleted plan.

Related errors


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