Repository navigation
Fix Cloud paid team limits for ID-only selected teams - #16318
Conversation
|
All contributors have signed the CLA ✍️ ✅ |
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. 🧰 Additional context used📚 Code guidelines (2)No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository: manaflow-ai/cmux/.coderabbit.yaml Review profile: ASSERTIVE Plan: Advanced Run ID: 📒 Files selected for processing (2)
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 0 remain after this review. 📝 WalkthroughWalkthroughTeam membership resolution now looks up details when the selected team lacks ChangesTeam billing resolution
Priority: ➖ Normal Estimated code review effort: 3 (Moderate) | ~20 minutes Change: Bug fix · Severity of issue fixed: Medium Suggested reviewers: Merge Risk: ⚪ Minimal · up to The change addresses paid-team billing for ID-only selected teams while preserving safe fallback behavior. No concrete merge-blocking issue remains in the supplied evidence; merge after normal checks pass. Security Architecture ReviewSecurity architecture risk: 🔵 Low · up to Team-ID matching and membership checks remain intact, and complete-membership refreshes reject incomplete pagination. The main residual risk is increased dependence on team lookups during authentication and temporary reuse of degraded billing results. No cross-team privilege expansion was demonstrated. Retained concerns Security review detailsSecurity Blast Radius
Trust Boundaries and Controls
Resilience and Maintainability Implications
Hardening Proposals
🚥 Pre-merge checks | ✅ 24 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (24 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
All reported issues were addressed across 2 files
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
CI failure attributionCI passes on Written by |
There was a problem hiding this comment.
All reported issues were addressed across 2 files (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
Keep partial Stack team pages out of identity snapshots and fall back to the selected team user plan when pagination repeats a cursor or reaches its bound. Preserve strict behavior for fresh and snapshot refresh paths.
There was a problem hiding this comment.
2 issues found across 2 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="web/services/vms/auth.ts">
<violation number="1" location="web/services/vms/auth.ts:844">
P2: An incomplete page walk can now determine the fallback billing team: with no `selectedTeam`, `resolveBillingTeam` treats a partial one-team result as the sole team or chooses a paid team from an incomplete set. Keep incomplete results from driving fallback billing selection; otherwise VM entitlements may use the wrong team's scope.</violation>
<violation number="2" location="web/services/vms/auth.ts:845">
P2: Native auth caches this incomplete result even though `completeTeamList` is false, so retries with the same tokens can keep using partial membership or the user-plan fallback for the cache TTL after pagination recovers. Skip native-cache writes when `completeTeamList` is false.</violation>
</file>
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
| // mark the partial result complete, so it is never snapshotted. | ||
| const listed = await listStackTeams(user, undefined); | ||
| listedTeamRaw = listed.teams; | ||
| completeTeamList = listed.complete; |
There was a problem hiding this comment.
P2: Native auth caches this incomplete result even though completeTeamList is false, so retries with the same tokens can keep using partial membership or the user-plan fallback for the cache TTL after pagination recovers. Skip native-cache writes when completeTeamList is false.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At web/services/vms/auth.ts, line 845:
<comment>Native auth caches this incomplete result even though `completeTeamList` is false, so retries with the same tokens can keep using partial membership or the user-plan fallback for the cache TTL after pagination recovers. Skip native-cache writes when `completeTeamList` is false.</comment>
<file context>
@@ -825,22 +825,36 @@ async function resolveStackTeamMembership(
+ // mark the partial result complete, so it is never snapshotted.
+ const listed = await listStackTeams(user, undefined);
+ listedTeamRaw = listed.teams;
+ completeTeamList = listed.complete;
+ }
+ } else if (options.listAllTeams === true) {
</file context>
| // Stack returns a broken or unexpectedly large pagination chain. Do not | ||
| // mark the partial result complete, so it is never snapshotted. | ||
| const listed = await listStackTeams(user, undefined); | ||
| listedTeamRaw = listed.teams; |
There was a problem hiding this comment.
P2: An incomplete page walk can now determine the fallback billing team: with no selectedTeam, resolveBillingTeam treats a partial one-team result as the sole team or chooses a paid team from an incomplete set. Keep incomplete results from driving fallback billing selection; otherwise VM entitlements may use the wrong team's scope.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At web/services/vms/auth.ts, line 844:
<comment>An incomplete page walk can now determine the fallback billing team: with no `selectedTeam`, `resolveBillingTeam` treats a partial one-team result as the sole team or chooses a paid team from an incomplete set. Keep incomplete results from driving fallback billing selection; otherwise VM entitlements may use the wrong team's scope.</comment>
<file context>
@@ -825,22 +825,36 @@ async function resolveStackTeamMembership(
+ // Stack returns a broken or unexpectedly large pagination chain. Do not
+ // mark the partial result complete, so it is never snapshotted.
+ const listed = await listStackTeams(user, undefined);
+ listedTeamRaw = listed.teams;
+ completeTeamList = listed.complete;
+ }
</file context>
|
Merge receipt for |
0906bcb fix: make main's full test suite pass again (manaflow-ai#16429) 11bfe00 Restore custom sidebar preview gallery (manaflow-ai#16535) 343dd1b web: sync all Hexclave webhooks into a validated, order-independent mirror (manaflow-ai#16339) 00547d5 ci: avoid blaming unrelated merges for compile failures (manaflow-ai#16533) b782440 fix(ci): provision Go for every iOS Release archive (manaflow-ai#16534) 3555618 Add a Jump to Bottom button to terminal panes (manaflow-ai#15382) 79febcf fix: tolerate delayed App Store Connect processing (manaflow-ai#16527) fcbf13c fix: export Foundation for remote paste policy (manaflow-ai#16525) 6d86537 Add What's New recap with an off / quiet / sheet setting (manaflow-ai#14876) 256d964 fix(xcstrings): keep conflict resolutions valid JSON (manaflow-ai#16071) 8473bdc fix: upload pasted images into private SSH directories (manaflow-ai#16523) 53c705c Show opt-in model, context %, and estimated cost next to agent status in the sidebar (manaflow-ai#14855) eba3c42 remote relay: permit scoped terminal paste (manaflow-ai#14915) e447665 fix: stop update relaunch prompts from looping (manaflow-ai#15702) 4a46320 Fix Cloud paid team limits for ID-only selected teams (manaflow-ai#16318) c266af9 test(cloud): pin the CLI tree's link error message through the bundled CLI (manaflow-ai#16515) 0059066 Calmer focus feedback: one short pulse, no flash while typing (manaflow-ai#14894) 65930fc fix(remote): preserve tmux split metadata (manaflow-ai#16398) 512817d docs: fill missing unreleased user-facing changes (manaflow-ai#16519) f204ade ci: nightly 120 Hz fling bench for the cmux-next agent pane (manaflow-ai#16511) 2be3b26 Remove generated custom sidebar preview art (manaflow-ai#16518)
Summary
When Stack Auth returns a selected team with only an ID, Cloud falls back to the user's free plan even when that team has a paid subscription. The VM list can then report
maxActiveVms: 0and a free-access expiry for a paid member.Hydrate the selected team's metadata before resolving billing. The bounded auth path uses one exact-ID lookup, and populated selected teams retain the existing fast path. Only details with the selected team's ID can replace it.
Fixes #16143.
Testing
82012fd6fce: the focused command below executed five tests; four failed with missing paid entitlements and the fallback case passed. Fix commit515aabf871c: all five passed. Follow-up commit96b8816aae5covers bounded auth requesting a different team and paginates complete membership lookup.cd web && bun run test tests/vm-route-auth.test.ts -t "ID-only selected team|does not borrow another paid"bun run test tests/vm-route-auth.test.ts tests/billing-team-resolution.test.ts tests/vm-pro-gate.test.ts: 119 passed. Coverage includes cookie/native list limits, bounded lookups for both requested and selected teams, paid seats, complete-list pagination, existing populated-team behavior, and missing matching details._snapshotRouteunused-variable warning. Portable repository verification passed.Changelog
Fixed: Cloud preserves paid team limits when the selected team's billing details need loading.
Summary by cubic
Fixes Cloud falling back to the user's free plan when the selected Stack team comes back with only an ID, which could report
maxActiveVms: 0and a free-access expiry for paid members. Fixes #16143.Written for commit 5daf1e6. Summary will update on new commits.
Summary by CodeRabbit