signalapp/Signal-Server · error · BadRequestException

Operation cannot be performed with the

Error message

Operation cannot be performed with the ${processor} payment provider

What it means

getCustomerAwareProcessor throws BadRequestException "Operation cannot be performed with the <processor> payment provider" when an operation that requires a customer-aware processor is invoked with GOOGLE_PLAY_BILLING or APPLE_APP_STORE, which have no direct customer/processor API in this service.

Solutions

  1. Use STRIPE or BRAINTREE as the processor for customer-aware operations
  2. Manage app-store subscriptions through the store's own APIs / the app-store-specific endpoints
  3. Validate the processor path parameter client-side before calling

Example fix

// before
PUT /v1/subscription/{subscriberId}/default_payment_method/GOOGLE_PLAY_BILLING/{token}
// after
PUT /v1/subscription/{subscriberId}/default_payment_method/STRIPE/{token}
Defensive patterns

Strategy: validation

Validate before calling

const CUSTOMER_AWARE = ['STRIPE','BRAINTREE'];
if (!CUSTOMER_AWARE.includes(processor)) throw new Error(`${processor} has no customer-aware operations`);

Type guard

const isCustomerAware = (p) => p === 'STRIPE' || p === 'BRAINTREE';

Prevention

When it happens

Trigger: Any subscriber operation that routes through getCustomerAwareProcessor (e.g. default payment method, subscription level changes via processor path) with processor=GOOGLE_PLAY_BILLING or APPLE_APP_STORE in the URL.

Common situations: Clients constructing processor-segmented URLs for app-store subscriptions; automation iterating all PaymentProvider values against customer endpoints.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of signalapp/Signal-Server@100ab61c82 (2026-09-09). Data as JSON: /api/errors/c58a3da1bf08ca3c. Report an issue: GitHub.

Appendix: source

Thrown at service/src/main/java/org/whispersystems/textsecuregcm/controllers/SubscriptionController.java:355

    final SubscriberCredentials subscriberCredentials =
        SubscriberCredentials.process(authenticatedAccount, subscriberId, clock);
    final Locale locale = getPayPalLocale(HeaderUtils.getAcceptableLanguagesForRequest(containerRequestContext));

    final BraintreeManager.PayPalBillingAgreementApprovalDetails billingAgreementApprovalDetails = subscriptionManager.addPaymentMethodToCustomer(
            subscriberCredentials,
            braintreeManager,
            getClientPlatform(userAgentString),
            (mgr, _) -> mgr.createPayPalBillingAgreement(request.returnUrl, request.cancelUrl, locale.toLanguageTag()));
              return new CreatePayPalBillingAgreementResponse(
        billingAgreementApprovalDetails.approvalUrl(),
        billingAgreementApprovalDetails.billingAgreementToken());
  }

  private CustomerAwareSubscriptionPaymentProcessor getCustomerAwareProcessor(PaymentProvider processor) {
    return switch (processor) {
      case STRIPE -> stripeManager;
      case BRAINTREE -> braintreeManager;
      case GOOGLE_PLAY_BILLING, APPLE_APP_STORE -> throw new BadRequestException("Operation cannot be performed with the " + processor + " payment provider");
    };
  }

  @POST
  @Path("/{subscriberId}/default_payment_method/{processor}/{paymentMethodToken}")
  @Consumes(MediaType.APPLICATION_JSON)
  @Produces(MediaType.APPLICATION_JSON)
  @ManagedAsync
  public Response setDefaultPaymentMethodWithProcessor(
      @Auth Optional<AuthenticatedDevice> authenticatedAccount,
      @PathParam("subscriberId") String subscriberId,
      @PathParam("processor") PaymentProvider processor,
      @PathParam("paymentMethodToken") @NotEmpty String paymentMethodToken) throws SubscriptionException, IOException {
    SubscriberCredentials subscriberCredentials =
        SubscriberCredentials.process(authenticatedAccount, subscriberId, clock);

    final CustomerAwareSubscriptionPaymentProcessor manager = getCustomerAwareProcessor(processor);

View on GitHub (pinned to 100ab61c82)