A failed read of an organization's plan position is shown to the member as holding nothing #197

Open
opened 2026-10-09 04:59:55 +00:00 by cgalo5758 · 0 comments
Owner

What happens

Found by reading, not yet reproduced. Three member paths read which tier the organization holds on a ladder and treat a database error in that read as holding nothing there:

  • Cancel, Keep and a switch. resolveLadderSubscription skips a pool whose attachment read fails, finds no rung and returns ErrNoActivePaidSubscription, so the member is told "There's no active subscription to change on this plan." The read error is dropped, so the log records the missing subscription and not the fault. Cancel and Keep reach this lookup directly. A switch reaches it after the Products page's own read of the same rows has succeeded. The switch preview gets the same answer through HasActiveSubscriptionOnLadder.
  • The switch confirmation. currentTierName returns an empty name on any failed read, so the confirmation and the refusal leave out the tier the member is on.
  • The entitlements panel. A pool whose attachment read fails gets the "No active plan" line.

The Products page, Checkout and the switch's offer check return the same failure as an error instead (the position loader in internal/server/plan_offer.go).

What should happen

A failed read is reported as a failure, as the Products page reports its own. The plan acts answer "We couldn't complete that change. Try again in a moment." and log the database error. The panel shows its load error instead of a plan line.

Where

internal/fulfillment/plan_change.go (resolveLadderSubscription); internal/server/member_products.go (currentTierName, GetEntitlements). Once #188 lands, all three read through one position query.

Why it matters

During a passing database fault, a member who pays for a plan is told they have no subscription or no plan, and the log hides the fault behind the same claim.

## What happens Found by reading, not yet reproduced. Three member paths read which tier the organization holds on a ladder and treat a database error in that read as holding nothing there: - **Cancel, Keep and a switch.** `resolveLadderSubscription` skips a pool whose attachment read fails, finds no rung and returns `ErrNoActivePaidSubscription`, so the member is told "There's no active subscription to change on this plan." The read error is dropped, so the log records the missing subscription and not the fault. Cancel and Keep reach this lookup directly. A switch reaches it after the Products page's own read of the same rows has succeeded. The switch preview gets the same answer through `HasActiveSubscriptionOnLadder`. - **The switch confirmation.** `currentTierName` returns an empty name on any failed read, so the confirmation and the refusal leave out the tier the member is on. - **The entitlements panel.** A pool whose attachment read fails gets the "No active plan" line. The Products page, Checkout and the switch's offer check return the same failure as an error instead (the position loader in `internal/server/plan_offer.go`). ## What should happen A failed read is reported as a failure, as the Products page reports its own. The plan acts answer "We couldn't complete that change. Try again in a moment." and log the database error. The panel shows its load error instead of a plan line. ## Where `internal/fulfillment/plan_change.go` (`resolveLadderSubscription`); `internal/server/member_products.go` (`currentTierName`, `GetEntitlements`). Once #188 lands, all three read through one position query. ## Why it matters During a passing database fault, a member who pays for a plan is told they have no subscription or no plan, and the log hides the fault behind the same claim.
cgalo5758 added the
kind
bug
area/billingarea/member-ui
labels 2026-10-09 04:59:55 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: wiki-cafe/member-console#197