plandex-ai/plandex · error

error storing default plan config: %v

Error message

error storing default plan config: %v

What it means

StoreDefaultPlanConfig wraps a failure of `UPDATE users SET default_plan_config = $1 WHERE id = $2` executed on the caller-supplied transaction (tx.Exec) with this message. Because it runs on a tx, this error typically also aborts the surrounding transaction via WithTx.

Source

Thrown at app/server/db/plan_config_helpers.go:61

	var config shared.PlanConfig
	err := Conn.Get(&config, query, userId)

	if err != nil {
		return nil, fmt.Errorf("error getting default plan config: %v", err)
	}

	return &config, nil
}

func StoreDefaultPlanConfig(userId string, config *shared.PlanConfig, tx *sqlx.Tx) error {
	query := `
		UPDATE users SET default_plan_config = $1 WHERE id = $2
	`

	_, err := tx.Exec(query, config, userId)

	if err != nil {
		return fmt.Errorf("error storing default plan config: %v", err)
	}

	return nil
}

View on GitHub (pinned to e2d772072e)

Solutions

  1. Ensure a valid, non-nil, still-open *sqlx.Tx is passed and that no earlier statement in the transaction already failed
  2. Inspect the wrapped cause: connection errors mean check Postgres health/DATABASE_URL and retry the whole transaction
  3. Confirm migrations define users.default_plan_config
  4. If the userId may not exist, check RowsAffected after Exec — a zero-row update succeeds silently and is a separate bug from this error

Example fix

// before
err = StoreDefaultPlanConfig(userId, config, tx) // tx may be dead after earlier error
// after
if err := doOtherWork(tx); err != nil {
    return err // abort early so tx isn't reused in a broken state
}
if err := StoreDefaultPlanConfig(userId, config, tx); err != nil {
    return err
}
Defensive patterns

Strategy: try-catch

Validate before calling

if tx == nil {
    return errors.New("StoreDefaultPlanConfig requires an active transaction")
}
var exists bool
Conn.Get(&exists, "SELECT EXISTS(SELECT 1 FROM users WHERE id=$1)", userId)

Try / catch

err := WithTx(ctx, "store default plan config", func(tx *sqlx.Tx) error {
    if err := StoreDefaultPlanConfig(userId, config, tx); err != nil {
        return fmt.Errorf("store default plan config for %s: %w", userId, err)
    }
    return nil
})
if err != nil { return err } // tx rolled back safely

Prevention

When it happens

Trigger: Called with a nil or already-committed/rolled-back *sqlx.Tx (nil pointer dereference or 'tx has been committed' error), the users row doesn't exist (silent zero-row update — not this error), DB connection lost, or the PlanConfig cannot be driver-encoded.

Common situations: Transaction context canceled mid-flight (WithTx with a canceled ctx); caller reuses a tx after an earlier error; connection-pool exhaustion; schema drift removing default_plan_config.

Related errors


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