plandex-ai/plandex · error

error adding org users: %v

Error message

error adding org users: %v

What it means

AddOrgDomainUsers wraps a failure of the bulk INSERT into orgs_users (with ON CONFLICT DO NOTHING) into 'error adding org users: %v'. Even though duplicates are skipped via the org_user_unique constraint, other insert failures still bubble up here.

Source

Thrown at app/server/db/org_helpers.go:174

		return fmt.Errorf("error getting org member role id: %v", err)
	}

	if len(usersForDomain) > 0 {
		// create org users for each user
		var valueStrings []string
		var valueArgs []interface{}
		for i, user := range usersForDomain {
			num := i * 3
			valueStrings = append(valueStrings, fmt.Sprintf("($%d, $%d, $%d)", num+1, num+2, num+3))
			valueArgs = append(valueArgs, orgId, user.Id, orgMemberRoleId)
		}

		// Join all value strings and execute a single query
		stmt := fmt.Sprintf("INSERT INTO orgs_users (org_id, user_id, org_role_id) VALUES %s ON CONFLICT ON CONSTRAINT org_user_unique DO NOTHING", strings.Join(valueStrings, ","))
		_, err = tx.Exec(stmt, valueArgs...)

		if err != nil {
			return fmt.Errorf("error adding org users: %v", err)
		}
	}

	return nil
}

func DeleteOrgUser(orgId, userId string, tx *sqlx.Tx) error {
	log.Printf("Deleting org user, org: %s | user: %s\n", orgId, userId)

	_, err := tx.Exec("DELETE FROM orgs_users WHERE org_id = $1 AND user_id = $2", orgId, userId)

	if err != nil {
		return fmt.Errorf("error deleting org member: %v", err)
	}

	return nil
}

View on GitHub (pinned to e2d772072e)

Solutions

  1. Check the wrapped %v for pq error code 23503 (FK) and verify org id and orgMemberRoleId are valid
  2. Chunk the batch insert (e.g. 1000 rows per statement) to stay under the 65535-parameter limit and avoid timeout-scale statements
  3. Confirm GetOrgMemberRoleId returned a live org_roles.id
  4. Retry the flow — ON CONFLICT DO NOTHING makes re-runs idempotent

Example fix

// before
stmt := fmt.Sprintf("INSERT INTO orgs_users ... VALUES %s ON CONFLICT ...", strings.Join(valueStrings, ","))
_, err = tx.Exec(stmt, valueArgs...)
// after
const chunk = 1000
for start := 0; start < len(usersForDomain); start += chunk {
    end := start + chunk
    if end > len(usersForDomain) { end = len(usersForDomain) }
    // build valueStrings/valueArgs for usersForDomain[start:end] and exec
}
Defensive patterns

Strategy: try-catch

Validate before calling

orgMemberRoleId, err := db.GetOrgMemberRoleId()
if err != nil { return err }
if len(usersForDomain)*3 > 60000 { /* chunk the batch */ }

Try / catch

err := db.AddOrgDomainUsers(orgId, domain, tx)
if err != nil {
    var pqErr *pq.Error
    if errors.As(err, &pqErr) && pqErr.Code == "23503" {
        return fmt.Errorf("orphan user/role reference: %s", pqErr.Detail)
    }
    return err
}

Prevention

When it happens

Trigger: The multi-row INSERT fails: FK violation (23503) because a user id or org_role_id doesn't exist, parameter-count mismatch in the generated $n placeholders, connection drop, or a very large user list exceeding Postgres parameter limits (65535).

Common situations: Domains with thousands of users producing more than 65535 bind parameters; role id stale after role-table changes; tx aborted by an earlier statement.

Related errors


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