overleaf/overleaf · warning · MissingBillingInfoError

This account has no billing info

Error message

This account has no billing info

What it means

RecurlyClient.getPaymentMethod fetches a user's billing info from Recurly. If Recurly returns a NotFoundError for the account's billing info, it throws MissingBillingInfoError — the Recurly account exists the call targets but has no payment method stored on file.

Source

Thrown at services/web/app/src/Features/Subscription/RecurlyClient.mjs:542

 */
async function resumeSubscriptionByUuid(subscriptionUuid) {
  return await client.resumeSubscription('uuid-' + subscriptionUuid)
}

/**
 * Get the payment method for the given user
 *
 * @param {string} userId
 * @return {Promise<PaymentMethod>}
 */
async function getPaymentMethod(userId) {
  let billingInfo

  try {
    billingInfo = await client.getBillingInfo(`code-${userId}`)
  } catch (error) {
    if (error instanceof recurly.errors.NotFoundError) {
      throw new MissingBillingInfoError('This account has no billing info', {
        userId,
      })
    }
    throw error
  }

  return paymentMethodFromApi(billingInfo)
}

/**
 * Get the configuration for a given add-on
 *
 * @param {string} planCode
 * @param {string} addOnCode
 * @return {Promise<PaymentProviderAddOn>}
 */
async function getAddOn(planCode, addOnCode) {
  const addOn = await client.getPlanAddOn(

View on GitHub (pinned to 28ad3b03b7)

Solutions

  1. Catch MissingBillingInfoError and redirect the user to add billing info before continuing
  2. Check whether the user has billing info on file (via this call guarded by try/catch) before operations requiring a payment method
  3. Catch the underlying recurly.errors.NotFoundError if handling at the Recurly client layer
  4. Verify the userId maps to the correct Recurly account code (code-<userId>) to rule out a lookup against the wrong account

Example fix

// before
const paymentMethod = await recurlyClient.getPaymentMethod(userId)
// after
let paymentMethod
try {
  paymentMethod = await recurlyClient.getPaymentMethod(userId)
} catch (err) {
  if (err instanceof MissingBillingInfoError) {
    return { paymentMethod: null, needsBillingInfo: true }
  }
  throw err
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
  const pm = await recurlyClient.getPaymentMethod(userId)
} catch (err) {
  if (err instanceof MissingBillingInfoError) {
    return { paymentMethod: null, needsBillingInfo: true }
  }
  throw err
}

Prevention

When it happens

Trigger: Calling getPaymentMethod(userId) for a Recurly account that has never saved a card/PayPal/billing address, e.g. a user who subscribed via a path that skipped billing-info collection.

Common situations: Group-plan admins who joined but never entered payment details; accounts migrated between providers losing billing info; SSO-created accounts; flows assuming a card on file after plan change.

Related errors


AI-assisted analysis of overleaf/overleaf@28ad3b03b7 (2026-09-03). Data as JSON: /api/errors/16878e9e13e2bd37. Report an issue: GitHub.