plandex-ai/plandex · error
error creating plan: %v
Error message
error creating plan: %v
What it means
This error wraps any failure from the INSERT into the 'plans' table inside CreatePlan (app/server/db/plan_helpers.go:59). The insert uses tx.QueryRow(...).Scan(...) with a RETURNING clause, so it fails when the INSERT itself errors or when scanning the returned id/created_at/updated_at fails. Because it runs inside a WithTx transaction, a failure here aborts the whole plan-creation transaction.
Source
Thrown at app/server/db/plan_helpers.go:59
Name: name,
PlanConfig: planConfig,
}
err = tx.QueryRow(
query,
orgId,
userId,
projectId,
name,
planConfig,
).Scan(
&plan.Id,
&plan.CreatedAt,
&plan.UpdatedAt,
)
if err != nil {
return fmt.Errorf("error creating plan: %v", err)
}
_, err = tx.Exec("INSERT INTO lockable_plan_ids (plan_id) VALUES ($1)", plan.Id)
if err != nil {
return fmt.Errorf("error inserting lockable plan id: %v", err)
}
// the one place where we do this to skip the locking queue
// ok to cheat this once since we're creating a new plan
repo := getGitRepo(orgId, plan.Id)
_, err = CreateBranch(repo, plan, nil, "main", tx)
if err != nil {
return fmt.Errorf("error creating main branch: %v", err)
}
log.Println("Created branch main")View on GitHub (pinned to e2d772072e)
Solutions
- Check the wrapped %v detail in logs for the underlying pq/lib/pq error code and address it specifically (unique_violation, foreign_key_violation, etc.)
- Verify the database schema matches migrations (run any pending migrations; confirm plans has id, created_at, updated_at, plan_config columns)
- Confirm the org_id, projectId, and userId passed to CreatePlan exist and the DB connection is healthy
- If it's a transient connection error, retry CreatePlan; the transaction rolls back cleanly so a retry is safe
Example fix
// before (hard to diagnose)
return fmt.Errorf("error creating plan: %v", err)
// after (surface the DB error class)
var pqErr *pq.Error
if errors.As(err, &pqErr) {
return fmt.Errorf("error creating plan: code=%s constraint=%s: %v", pqErr.Code, pqErr.Constraint, pqErr)
}
return fmt.Errorf("error creating plan: %w", err) Defensive patterns
Strategy: try-catch
Validate before calling
// Go: verify inputs and DB reachability before CreatePlan
if orgId == "" || projectId == "" || userId == "" || name == "" {
return fmt.Errorf("create plan: orgId, projectId, userId and name are required")
}
if err := db.PingContext(ctx); err != nil {
return fmt.Errorf("database unreachable: %w", err)
} Type guard
func asPQError(err error) (*pq.Error, bool) {
var pqErr *pq.Error
if errors.As(err, &pqErr) {
return pqErr, true
}
return nil, false
} Try / catch
plan, err := db.CreatePlan(ctx, orgId, projectId, userId, name)
if err != nil {
var pqErr *pq.Error
if errors.As(err, &pqErr) && pqErr.Code == "23505" {
// duplicate plan: surface a friendly message
return nil, ErrPlanAlreadyExists
}
return nil, fmt.Errorf("create plan failed: %w", err)
} Prevention
- Keep DB migrations in lockstep with the deployed server version
- Validate org/project/user ids exist before calling CreatePlan
- Handle the specific pq error codes (23505 duplicate, 23503 FK) in the caller
- Monitor DB connectivity and pool saturation to catch transient causes
When it happens
Trigger: Calling CreatePlan when the plans insert violates a constraint (e.g. duplicate plan name if unique, invalid org_id/user_id/project_id foreign keys), when the database connection is down, when plan_config serialization is incompatible with the column type, or when Scan cannot decode the RETURNING columns (schema/type mismatch between the Plan struct and the table).
Common situations: Database migrations out of sync with the deployed code (missing or altered plans columns), Postgres connection pool exhaustion or transient connection drops, FK violations from a project or user that was deleted concurrently, or running against an older Postgres that rejects the plan_config format.
Related errors
- error inserting lockable plan id: %v
- error updating user num_non_draft_plans: %v
- error creating invite: %v
- error deleting invite: %v
- error accepting invite: %v
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/f3066b7b4e717b94.
Report an issue: GitHub.