{"record":{"id":"7cafe913d1423463","repo":"overleaf/overleaf","slug":"invalid-country","errorCode":null,"errorMessage":"Invalid country","messagePattern":"Invalid country","errorType":"validation","errorClass":"InvalidError","httpStatus":400,"severity":"error","filePath":"services/web/app/src/Features/Subscription/RecurlyWrapper.mjs","lineNumber":952,"sourceCode":"    })\n  }\n  if (subscriptionDetails.ITMReferrer) {\n    customFields.push({\n      name: 'itm_referrer',\n      value: subscriptionDetails.ITMReferrer,\n    })\n  }\n  return { custom_field: customFields }\n}\n\nfunction getAddressFromSubscriptionDetails(\n  subscriptionDetails,\n  includeCompanyInfo\n) {\n  const { address } = subscriptionDetails\n\n  if (!address || !address.country) {\n    throw new Errors.InvalidError({\n      message: 'Invalid country',\n      info: {\n        public: {\n          message: 'Invalid country',\n        },\n      },\n    })\n  }\n\n  const addressObject = {\n    address1: address.address1,\n    address2: address.address2 || '',\n    city: address.city || '',\n    state: address.state || '',\n    zip: address.zip || '',\n    country: address.country,\n  }\n","sourceCodeStart":934,"sourceCodeEnd":970,"githubUrl":"https://github.com/overleaf/overleaf/blob/28ad3b03b71cb4311decdcb55c36b33ec10d72db/services/web/app/src/Features/Subscription/RecurlyWrapper.mjs#L934-L970","documentation":"While building Recurly billing/purchase XML, this code validates the address from subscriptionDetails and throws Errors.InvalidError with message 'Invalid country' when the address is missing entirely or address.country is empty — Recurly requires a valid country on billing addresses.","triggerScenarios":"Calling a RecurlyWrapper purchase/subscription function with subscriptionDetails whose address is undefined, or whose address.country is null/empty string (e.g. a form submitted without selecting a country).","commonSituations":"Signup forms with optional country fields; IP-geolocation-based country inference failing and leaving country blank; users with addresses saved before country became required; regional deployments not enforcing country validation client-side.","solutions":["Validate that subscriptionDetails.address and address.country are present before calling the Recurly wrapper","Add a required country field / client-side validation in the address form","Default the country from user geolocation or IP when missing, with user confirmation","Catch Errors.InvalidError and show 'Please provide a country' to the user"],"exampleFix":"// before\nawait RecurlyWrapper.purchase(subscriptionDetails)\n// after\nif (!subscriptionDetails.address?.country) {\n  throw new Error('country is required')\n}\nawait RecurlyWrapper.purchase(subscriptionDetails)","handlingStrategy":"validation","validationCode":"if (!subscriptionDetails?.address?.country) {\n  throw new Error('country is required before calling Recurly')\n}","typeGuard":"function hasValidCountry(details) {\n  return (\n    typeof details?.address?.country === 'string' &&\n    details.address.country.length > 0\n  )\n}","tryCatchPattern":"try {\n  await RecurlyWrapper.purchase(subscriptionDetails)\n} catch (err) {\n  if (err instanceof Errors.InvalidError) {\n    return { error: 'invalid-address', field: 'country' }\n  }\n  throw err\n}","preventionTips":["Make country a required field in address forms","Validate addresses client-side before submitting to Recurly","Backfill country for legacy addresses lacking it","Use ISO country codes consistently"],"tags":["subscription","recurly","validation","address","country"],"backgroundTag":"invalid-address-validation","analyzedSha":"28ad3b03b71cb4311decdcb55c36b33ec10d72db","analyzedAt":"2026-09-03T02:10:22.807Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T07:17:11.731Z"}