plandex-ai/plandex · error

Error storing plan config

Error message

Error storing plan config

What it means

db.StorePlanConfig(planId, req.Config) failed after the body decoded successfully, so the handler returns HTTP 500. This is a server-side persistence failure writing the new plan config, not a client error.

Source

Thrown at app/server/handlers/plan_config.go:85

	log.Println("planId: ", planId)

	plan := authorizePlan(w, planId, auth)
	if plan == nil {
		return
	}

	var req shared.UpdatePlanConfigRequest
	err := json.NewDecoder(r.Body).Decode(&req)
	if err != nil {
		log.Println("Error decoding request body: ", err)
		http.Error(w, "Error decoding request body", http.StatusBadRequest)
		return
	}

	err = db.StorePlanConfig(planId, req.Config)
	if err != nil {
		log.Println("Error storing plan config: ", err)
		http.Error(w, "Error storing plan config", http.StatusInternalServerError)
		return
	}

	log.Println("UpdatePlanConfigHandler processed successfully")
}

func GetDefaultPlanConfigHandler(w http.ResponseWriter, r *http.Request) {
	log.Println("Received request for GetDefaultPlanConfigHandler")

	auth := Authenticate(w, r, true)
	if auth == nil {
		return
	}

	config, err := db.GetDefaultPlanConfig(auth.User.Id)
	if err != nil {
		log.Println("Error getting default plan config: ", err)
		http.Error(w, "Error getting default plan config", http.StatusInternalServerError)

View on GitHub (pinned to e2d772072e)

Solutions

  1. Check server logs for "Error storing plan config: <err>" for the root cause
  2. Verify the DB is writable and migrations are current
  3. Retry the request if the failure was a transient deadlock/serialization error
  4. Reduce config payload size or widen the storage column if limits are hit
Defensive patterns

Strategy: retry

Validate before calling

// client: retry only on 500; 400s mean bad body
let lastErr;
for (let i = 0; i < 3; i++) {
  const res = await tryStore(planId, config);
  if (res.ok) return;
  if (res.status !== 500) break; // do not retry client errors
  lastErr = res;
  await sleep(2 ** i * 250);
}

Try / catch

try {
  await updatePlanConfig(planId, config);
} catch (e) {
  if (e.status === 500) { await backoffRetry(e, { attempts: 3 }); }
  else throw e;
}

Prevention

When it happens

Trigger: Update-plan-config call when the plan_configs table is missing/locked, the DB transaction fails (deadlock, serialization failure, disk full), or the config value exceeds column limits or violates constraints.

Common situations: Database read-only replica receiving writes, migrations not applied, disk full on the DB host, concurrent updates deadlocking, config payload too large for the storage column.

Related errors


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