plandex-ai/plandex · error

error getting org owner role id: %v

Error message

error getting org owner role id: %v

What it means

GetOrgOwnerRoleId is a memoized lookup of the 'owner' org_roles row id. When the cached global orgOwnerRoleId is empty it calls cacheOrgOwnerRoleId, and if that DB query (Conn.Get on 'SELECT id FROM org_roles WHERE name = owner') fails, the underlying error is wrapped with this message. It means the role id could not be resolved from the database.

Source

Thrown at app/server/db/rbac_helpers.go:15

package db

import (
	"fmt"
	"log"
)

var orgOwnerRoleId string
var orgMemberRoleId string

func GetOrgOwnerRoleId() (string, error) {
	if orgOwnerRoleId == "" {
		err := cacheOrgOwnerRoleId()
		if err != nil {
			return "", fmt.Errorf("error getting org owner role id: %v", err)
		}
	}

	if orgOwnerRoleId == "" {
		return "", fmt.Errorf("org owner role id is empty")
	}

	return orgOwnerRoleId, nil
}

func GetOrgMemberRoleId() (string, error) {
	if orgMemberRoleId == "" {
		err := cacheOrgMemberRoleId()
		if err != nil {
			return "", fmt.Errorf("error getting org member role id: %v", err)
		}
	}

View on GitHub (pinned to e2d772072e)

Solutions

  1. Run the schema migrations/seed that insert the 'owner' row into org_roles
  2. Verify the DB connection (Conn) is initialized via MustInitDb before any org operations
  3. Check DATABASE_URL / connectivity with a direct psql query: SELECT id FROM org_roles WHERE name = 'owner';
  4. Inspect the wrapped inner error (%v) for sql.ErrNoRows vs connection errors to decide between seed-data and connectivity fixes

Example fix

// before
role, err := GetOrgOwnerRoleId()
if err != nil { return err }
// after
if err := CacheOrgRoleIds(); err != nil {
	log.Fatalf("startup: org role ids unavailable: %v", err)
}
role, err := GetOrgOwnerRoleId()
Defensive patterns

Strategy: try-catch

Validate before calling

// before calling CreateOrg / AddToOrgForDomain
rows, err := db.Query("SELECT count(*) FROM org_roles WHERE name = 'owner'")
if err != nil || singleInt(rows) == 0 {
	return fmt.Errorf("org_roles not seeded; run migrations")
}

Type guard

func hasOwnerRole(ctx context.Context, db *sql.DB) bool {
	var n int
	if err := db.QueryRowContext(ctx, "SELECT count(*) FROM org_roles WHERE name = 'owner'").Scan(&n); err != nil {
		return false
	}
	return n > 0
}

Try / catch

ownerRoleId, err := GetOrgOwnerRoleId()
if err != nil {
	var noRows = strings.Contains(err.Error(), "sql: no rows")
	if noRows {
		return fmt.Errorf("org_roles seed data missing: %w", err)
	}
	return fmt.Errorf("database unavailable: %w", err)
}

Prevention

When it happens

Trigger: Calling CreateOrg, AddToOrgForDomain or DeleteOrgUserHandler when the org_roles table is missing, has no 'owner' row, the DB connection is down, or Conn was not initialized before the first call.

Common situations: Fresh database created without role seed data; DB migrations not run; wrong DATABASE_URL pointing at an empty/uninitialized database; transient DB outage or connection-pool exhaustion at startup.

Related errors


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