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
- Check the wrapped %v for pq error code 23503 (FK) and verify org id and orgMemberRoleId are valid
- Chunk the batch insert (e.g. 1000 rows per statement) to stay under the 65535-parameter limit and avoid timeout-scale statements
- Confirm GetOrgMemberRoleId returned a live org_roles.id
- 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
- Chunk bulk inserts to stay under Postgres's 65535 bind-parameter limit
- Use ON CONFLICT DO NOTHING (already present) so retries are idempotent
- Verify role ids are live before batch insert
- Skip users deleted concurrently by re-fetching within the same transaction
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
- error adding org membership: %v
- error deleting org member: %v
- error adding convo tokens: %v
- error checking settings: %v
- error creating postgres driver: %v
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/7b337da90b0b4e67.
Report an issue: GitHub.