{"record":{"id":"1e5158c5aaa6c07b","repo":"nopSolutions/nopCommerce","slug":"checkout-address-notfound","errorCode":null,"errorMessage":"Checkout.Address.NotFound","messagePattern":"Checkout\\.Address\\.NotFound","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/Presentation/Nop.Web/Controllers/CheckoutController.cs","lineNumber":1546,"sourceCode":"            var store = await _storeContext.GetCurrentStoreAsync();\r\n            var cart = await _shoppingCartService.GetShoppingCartAsync(customer, ShoppingCartType.ShoppingCart, store.Id);\r\n\r\n            if (!cart.Any())\r\n                throw new Exception(\"Your cart is empty\");\r\n\r\n            if (!_orderSettings.OnePageCheckoutEnabled)\r\n                throw new Exception(\"One page checkout is disabled\");\r\n\r\n            if (await _customerService.IsGuestAsync(customer) && !_orderSettings.AnonymousCheckoutAllowed)\r\n                throw new Exception(\"Anonymous checkout is not allowed\");\r\n\r\n            _ = int.TryParse(form[\"billing_address_id\"], out var billingAddressId);\r\n\r\n            if (billingAddressId > 0)\r\n            {\r\n                //existing address\r\n                var address = await _customerService.GetCustomerAddressAsync(customer.Id, billingAddressId)\r\n                              ?? throw new Exception(await _localizationService.GetResourceAsync(\"Checkout.Address.NotFound\"));\r\n\r\n                customer.BillingAddressId = address.Id;\r\n                await _customerService.UpdateCustomerAsync(customer);\r\n            }\r\n            else\r\n            {\r\n                if (await _customerService.IsGuestAsync(customer) && _taxSettings.EuVatEnabled && _taxSettings.EuVatEnabledForGuests)\r\n                {\r\n                    var warning = await SaveCustomerVatNumberAsync(model.VatNumber, customer);\r\n                    if (!string.IsNullOrEmpty(warning))\r\n                        ModelState.AddModelError(\"\", warning);\r\n                }\r\n\r\n                //new address\r\n                var newAddress = model.BillingNewAddress;\r\n\r\n                //custom address attributes\r\n                var customAttributes = await _addressAttributeParser.ParseCustomAttributesAsync(form, NopCommonDefaults.AddressAttributeControlName);\r","sourceCodeStart":1528,"sourceCodeEnd":1564,"githubUrl":"https://github.com/nopSolutions/nopCommerce/blob/64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2/src/Presentation/Nop.Web/Controllers/CheckoutController.cs#L1528-L1564","documentation":"Thrown by OpcSaveBilling after the ?? null-coalescing operator when GetCustomerAddressAsync(customer.Id, billingAddressId) returns null. The client supplied a billing_address_id > 0 that does not map to an address owned by that customer. The message is the localized resource key 'Checkout.Address.NotFound' resolved through ILocalizationService. It signals stale/invalid address selection data, not a server error.","triggerScenarios":"Client posts form['billing_address_id'] = <positive id> for an address that the customer does not own or that no longer exists (deleted, belongs to another account, post-migration ID mismatch). Happens when a stored address list is out of sync with the form.","commonSituations":"Customer deleted the address in another tab but the dropdown still lists it; address book migrated with new IDs while the page cache holds old IDs; address shared across merged accounts; tampered/curled request with an arbitrary id.","solutions":["Refresh the address dropdown from the customer's actual address book before submit.","Drop billing_address_id from the post and submit as a new (ShippingNewAddress/BillingNewAddress) address.","Verify the address id passed is one returned by GetAddressesByCustomerId for that customer.","If migrating, remap legacy address IDs to new ones."],"exampleFix":"// before: posting a stale id\nform[\"billing_address_id\"] = oldDeletedAddressId;\n// after: validate against the address book before posting\nvar mine = await _customerService.GetAddressesByCustomerIdAsync(customer.Id);\nif (!mine.Any(a => a.Id == billingAddressId)) { /* send 0 to create a new address */ }","handlingStrategy":"validation","validationCode":"// Validate the chosen address id belongs to the customer before posting.\nvar owned = (await _customerService.GetAddressesByCustomerIdAsync(customer.Id)).Select(a => a.Id);\nif (!owned.Contains(billingAddressId)) billingAddressId = 0; // fall back to new address","typeGuard":null,"tryCatchPattern":"const data = await res.json();\nif (data.error && /address/i.test(data.message)) {\n  await refreshAddressBook(); // re-pull the customer's addresses\n  selectFirstAddress();\n}","preventionTips":["Render the address dropdown from GetAddressesByCustomerIdAsync at render time.","After an address is deleted elsewhere, invalidate the dropdown.","Treat a missing id as 'create new address' rather than posting a stale id."],"tags":["checkout","opc","billing","address","validation","nopcommerce"],"backgroundTag":null,"analyzedSha":"64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2","analyzedAt":"2026-08-13T21:19:38.062Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}