Skip to content

Org-sponsored checkout: lapsed contract / no active assignment and the dunning-suspend gate answer 500 UNKNOWN_ERROR instead of a business code #1467

Description

@teetangh

What happens

lib/payments/operations/checkout.ts throws a bare new Error("No active program assignment covers this booking. …") (~L2665) when the member's organisation has no ACTIVE ProgramAssignment for the booking (expired contract, closed programme). The message matches nothing in BUSINESS_ERROR_PATTERNS (lib/errors/classification/payment-error-classification.ts), so classifyError falls through to UNKNOWN_ERROR / 500. The client cannot tell "ask your admin, the contract lapsed" from a crash, and Sentry records a false incident for a routine refusal.

The ENABLE_DUNNING_SUSPEND gate two screens up (~L2528, "…has an overdue invoice… suspended from new sponsored bookings…") is the same shape and would 500 identically once that flag is on.

Evidence (deploy-preview-1422, 2026-09-05, wave 2A)

Membership 8f261963-6a94-4b4e-9745-0adec4b1b896 in org 161fb79c-5631-4ca3-944c-9ec9746efe72 with only a CLOSED/EXPIRED assignment (effectiveTo 2026-08-12). POST /api/checkout with that organizationId:

HTTP 500 {"error":"No active program assignment covers this booking...","errorType":"UNKNOWN_ERROR"}

Fix (fold into #1460, which owns the modelled-outcome rethrow)

Throw typed errors with a stable code and status — PROGRAM_ASSIGNMENT_INACTIVE (409) and BILLING_SUSPENDED_DUNNING (402 or 409) — in the same shape as DomainVerificationRequiredError / WalletFrozenError, register both in BUSINESS_ERROR_CODES with actionable toasts, and let the isBusinessErrorCode rethrow from #1460 carry them to the route. One pin.

Found by the wave 2A enterprise run of the finance train (plan §8).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    EnterpriseEnterprise tier — B2B org features, Architecture 4bugSomething isn't workingfinancePayments, refunds, earnings, payouts, invoicing, ledgerlaunch: pre-mvpGates launch — money, data, or a failure we would not detectpriority: highHigh priority — needs attention soon

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions