plandex-ai/plandex · error

Error getting org user: {err.Error()}

Error message

Error getting org user: {err.Error()}

What it means

The handler could not fetch the target org-user row via db.GetOrgUser(userId, auth.OrgId), so the permission check cannot be built. The error surfaces as HTTP 500 with the raw DB error appended, even though a missing target user is really a client-side 'not found' situation.

Source

Thrown at app/server/handlers/users.go:135

	if org.IsTrial {
		writeApiError(w, shared.ApiError{
			Type:   shared.ApiErrorTypeTrialActionNotAllowed,
			Status: http.StatusForbidden,
			Msg:    "Trial user can't delete users",
		})
		return
	}

	vars := mux.Vars(r)
	userId := vars["userId"]

	log.Println("userId: ", userId)

	orgUser, err := db.GetOrgUser(userId, auth.OrgId)

	if err != nil {
		log.Printf("Error getting org user: %v\n", err)
		http.Error(w, "Error getting org user: "+err.Error(), http.StatusInternalServerError)
		return
	}

	// ensure current user can remove target user
	removePermission := shared.Permission(strings.Join([]string{string(shared.PermissionRemoveUser), orgUser.OrgRoleId}, "|"))

	if !auth.HasPermission(removePermission) {
		log.Printf("User does not have permission to remove user with role: %v\n", orgUser.OrgRoleId)
		http.Error(w, "User does not have permission to remove user with role: "+orgUser.OrgRoleId, http.StatusForbidden)
		return
	}

	// verify user is org member
	isMember, err := db.ValidateOrgMembership(userId, auth.OrgId)

	if err != nil {
		log.Printf("Error validating org membership: %v\n", err)
		http.Error(w, "Error validating org membership: "+err.Error(), http.StatusInternalServerError)

View on GitHub (pinned to e2d772072e)

Solutions

  1. Confirm the userId path parameter matches an existing row in org_users for the caller's org
  2. Treat sql.ErrNoRows as 404 instead of 500 so clients can detect 'already deleted'
  3. Trim/normalize the userId before lookup and verify the client is using the org-scoped user id
  4. Check for concurrent deletions if this occurs during retries

Example fix

// before
if err != nil {
    http.Error(w, "Error getting org user: "+err.Error(), http.StatusInternalServerError)
    return
}
// after
if errors.Is(err, sql.ErrNoRows) {
    http.Error(w, "org user not found", http.StatusNotFound)
    return
} else if err != nil {
    http.Error(w, "internal error", http.StatusInternalServerError)
    return
}
Defensive patterns

Strategy: validation

Validate before calling

var exists bool
err := db.QueryRow(
    "SELECT EXISTS(SELECT 1 FROM org_users WHERE user_id=$1 AND org_id=$2)",
    userId, auth.OrgId).Scan(&exists)
if err == nil && !exists {
    return errors.New("target user not in this org")
}

Type guard

func orgUserExists(db *sqlx.DB, userId, orgId string) bool {
    var ok bool
    _ = db.Get(&ok, "SELECT EXISTS(SELECT 1 FROM org_users WHERE user_id=$1 AND org_id=$2)", userId, orgId)
    return ok
}

Try / catch

orgUser, err := db.GetOrgUser(userId, auth.OrgId)
if err != nil {
    if errors.Is(err, sql.ErrNoRows) {
        http.Error(w, "org user not found", http.StatusNotFound)
    } else {
        http.Error(w, "internal error", http.StatusInternalServerError)
    }
    return
}

Prevention

When it happens

Trigger: Calling DELETE on a user whose userId path parameter has no corresponding org_user row for the authenticated org — wrong userId, user belongs to a different org, or the row was already deleted.

Common situations: Client passes an account-level userId instead of the org-scoped one; retrying an already-successful delete; userId casing/whitespace differences; user was removed concurrently.

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


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