plandex-ai/plandex · error
error getting default plan config: %v
Error message
error getting default plan config: %v
What it means
Inside CreatePlan's WithTx callback, an error from GetDefaultPlanConfig(userId) is re-wrapped with this identical message ('error getting default plan config'). It means the new plan's starting config could not be loaded from the user's row — usually because the userId doesn't exist in users (sql.ErrNoRows) — and causes the whole 'create plan' transaction to roll back.
Source
Thrown at app/server/db/plan_helpers.go:30
"strconv"
"time"
shared "plandex-shared"
"github.com/google/uuid"
"github.com/jmoiron/sqlx"
"github.com/lib/pq"
"github.com/sashabaranov/go-openai"
)
func CreatePlan(ctx context.Context, orgId, projectId, userId, name string) (*Plan, error) {
var plan *Plan
err := WithTx(ctx, "create plan", func(tx *sqlx.Tx) error {
planConfig, err := GetDefaultPlanConfig(userId)
if err != nil {
return fmt.Errorf("error getting default plan config: %v", err)
}
query := `INSERT INTO plans (org_id, owner_id, project_id, name, plan_config)
VALUES ($1, $2, $3, $4, $5)
RETURNING id, created_at, updated_at`
plan = &Plan{
OrgId: orgId,
OwnerId: userId,
ProjectId: projectId,
Name: name,
PlanConfig: planConfig,
}
err = tx.QueryRow(
query,
orgId,
userId,View on GitHub (pinned to e2d772072e)
Solutions
- Unwrap the nested cause: 'no rows in result set' means the userId is invalid — verify the user exists/authenticates before CreatePlan
- Apply migrations / seed data if users.default_plan_config or the users row is missing
- For scan errors, inspect and repair the user's default_plan_config JSON
- On transient connection errors, retry CreatePlan after DB health is restored (the tx rolled back cleanly)
Example fix
// before
planConfig, err := GetDefaultPlanConfig(userId)
if err != nil {
return fmt.Errorf("error getting default plan config: %v", err)
}
// after: fail fast with a distinct not-found path
planConfig, err := GetDefaultPlanConfig(userId)
if err != nil {
if strings.Contains(err.Error(), "no rows in result set") {
return fmt.Errorf("user %s not found: %w", userId, err)
}
return fmt.Errorf("error getting default plan config: %w", err)
} Defensive patterns
Strategy: validation
Validate before calling
// verify user exists before CreatePlan
var exists bool
if err := Conn.Get(&exists, "SELECT EXISTS(SELECT 1 FROM users WHERE id=$1)", userId); err != nil || !exists {
return nil, fmt.Errorf("cannot create plan: user %s not found", userId)
} Try / catch
plan, err := CreatePlan(ctx, orgId, projectId, userId, name)
if err != nil {
if strings.Contains(err.Error(), "no rows in result set") {
return nil, fmt.Errorf("user has no default plan config / not found")
}
log.Printf("CreatePlan: %v", err)
return nil, err
} Prevention
- Authenticate and resolve the user row before starting plan creation
- Give users a default_plan_config at account creation (NOT NULL DEFAULT '{}')
- Keep WithTx scopes short to minimize rollback blast radius
- Unwrap nested errors with %w and errors.Is for cleaner cause detection
When it happens
Trigger: CreatePlan runs with a userId that has no users row, a DB connection failure, or a default_plan_config value that can't scan into shared.PlanConfig; the WithTx('create plan') transaction then rolls back and no plan is created.
Common situations: Plan creation triggered by a stale or forged session whose user was deleted; environment where user seed data is missing; corrupted default_plan_config JSON; transient Postgres outage during plan creation.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
- error adding org user: %v
- error getting plan config: %v
- error getting default plan config: %v
- error storing default plan config: %v
- error adding plan context tokens: %v
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/2799e8c82c9dc57b.
Report an issue: GitHub.