Skip to content

fix(invite): honor --role when re-inviting an existing member#234

Merged
cvince merged 1 commit into
mainfrom
fix/invite-honor-role
Jun 9, 2026
Merged

fix(invite): honor --role when re-inviting an existing member#234
cvince merged 1 commit into
mainfrom
fix/invite-honor-role

Conversation

@cvince

@cvince cvince commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

What

capy invite <existing-member> reused the member's current role and skipped role resolution entirely, so an explicit --role (or an interactive role change) was silently ignored — re-inviting to promote/demote was a no-op. It was also fragile across kick → re-invite: if listMemberDetails read a not-yet-propagated WorkOS membership, the stale role was kept.

Fix

Take the silent re-issue path only when no role is requested:

if (existingMember && !opts.role) {
  // pure key re-issue: keep current role + projects
} else {
  // resolve role normally (--role / prompt / default) and project scope;
  // default project scope to the member's existing projects on re-issue
}

The service already supports this — addUserToOrgWithRole catches the 409 and updateMembershipRoles when the requested role differs ("re-inviting to promote is a silent no-op"). So sending the requested role is all that's needed, and it's race-proof (the requested role wins even if a stale membership is read).

How it surfaced

The e2e protected-branch test failed because under the harness the CLI runs non-interactively (piped stdin → isInteractive() is false), so the role prompt never ran and re-invite-as-admin fell back to member. The harness is being fixed separately (pass --role explicitly) in the monorepo; this PR makes the CLI honor that role on re-invite.

Tests

Full monorepo e2e suite green (44/44) against the dev service with this + the harness fix. No CLI unit tests touch this path's role branching; behavior verified end-to-end.

Re-inviting an existing member reused their current role and skipped role
resolution, so an explicit --role (or interactive role change) was silently
ignored — re-inviting to promote/demote was a no-op. It was also fragile
across kick -> re-invite: if listMemberDetails read a not-yet-propagated
membership, the stale role was kept.

Take the silent re-issue path only when no role is requested
(existingMember && !opts.role); otherwise resolve the role normally and let
the service's addUserToOrgWithRole upgrade the membership. Keep the member's
existing project scope by default on re-issue.

Surfaced by the e2e protected-branch test: under the harness the CLI runs
non-interactively (piped stdin), so the interactive role prompt never ran
and re-invite-as-admin silently fell back to member.
@cvince cvince merged commit 89d5a43 into main Jun 9, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant