plandex-ai/plandex · error

Error creating plan:

Error message

Error creating plan: 

What it means

CreatePlanHandler returns this 500 when db.CreatePlan fails to insert the new plan row. The database error text is appended to the response body. The count check succeeded but the actual INSERT/update of plan state failed.

Source

Thrown at app/server/handlers/plans_crud.go:107

				log.Printf("Error checking if plan exists: %v\n", err)
				http.Error(w, "Error checking if plan exists: "+err.Error(), http.StatusInternalServerError)
				return
			}

			if count == 0 {
				break
			}

			name = originalName + "." + fmt.Sprint(i)
			i++
		}
	}

	plan, err := db.CreatePlan(r.Context(), auth.OrgId, projectId, auth.User.Id, name)

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

	resp := shared.CreatePlanResponse{
		Id:   plan.Id,
		Name: plan.Name,
	}

	bytes, err := json.Marshal(resp)

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

	w.Write(bytes)

View on GitHub (pinned to e2d772072e)

Solutions

  1. Read the wrapped database error in the response body/server log (e.g. unique violation vs context canceled)
  2. Retry the request if it was a transient connection error or a name-collision race (the suffix loop will pick the next name)
  3. Verify the project still exists and the user belongs to the org before calling
  4. Check Postgres health: disk space, connection limits, and that the transaction wasn't rolled back by serialization failure

Example fix

// before
plan, err := db.CreatePlan(r.Context(), auth.OrgId, projectId, auth.User.Id, name)
if err != nil { http.Error(w, "Error creating plan: "+err.Error(), http.StatusInternalServerError); return }
// after
plan, err := db.CreatePlan(r.Context(), auth.OrgId, projectId, auth.User.Id, name)
if err != nil {
	if r.Context().Err() != nil { return } // client gone, don't log as server error
	var pgErr *pgconn.PgError
	if errors.As(err, &pgErr) && pgErr.Code == "23505" { name = name + ".2"; /* retry once */ }
	
}
Defensive patterns

Strategy: retry

Validate before calling

if r.Context().Err() != nil { return } // don't attempt insert after client cancelled

Type guard

func isUniqueViolation(err error) bool { var pgErr *pgconn.PgError; return errors.As(err, &pgErr) && pgErr.Code == "23505" }

Try / catch

plan, err := db.CreatePlan(r.Context(), orgId, projectId, userId, name)
if err != nil {
	if isUniqueViolation(err) { /* retry with suffixed name */ }
	if isTransientDBErr(err) { /* retry with backoff */ }
	http.Error(w, "Error creating plan", http.StatusInternalServerError)
	return
}

Prevention

When it happens

Trigger: POST create-plan call where db.CreatePlan(r.Context(), orgId, projectId, userId, name) fails: foreign-key violation (project or user row missing), unique constraint race on the name suffix, context cancelled by the client, or DB connection loss during the write.

Common situations: Client disconnects mid-request cancelling the context; two concurrent creates racing past the COUNT check onto a unique index; project deleted between authorization and insert; Postgres disk full or read-only replica promoted incorrectly.

Related errors


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