nopSolutions/nopCommerce · error · Exception

Primary exchange rate currency cannot be loaded

Error message

Primary exchange rate currency cannot be loaded

What it means

Thrown by ConvertToPrimaryExchangeRateCurrencyAsync as a plain Exception when GetCurrencyByIdAsync(PrimaryExchangeRateCurrencyId) returns null. The primary exchange-rate currency must exist for any currency conversion to the base currency.

Source

Thrown at src/Libraries/Nop.Services/Directory/CurrencyService.cs:245

        result = await ConvertToPrimaryExchangeRateCurrencyAsync(result, sourceCurrencyCode);
        result = await ConvertFromPrimaryExchangeRateCurrencyAsync(result, targetCurrencyCode);
        return result;
    }

    /// <summary>
    /// Converts to primary exchange rate currency 
    /// </summary>
    /// <param name="amount">Amount</param>
    /// <param name="sourceCurrencyCode">Source currency code</param>
    /// <returns>
    /// A task that represents the asynchronous operation
    /// The task result contains the converted value
    /// </returns>
    public virtual async Task<decimal> ConvertToPrimaryExchangeRateCurrencyAsync(decimal amount, Currency sourceCurrencyCode)
    {
        ArgumentNullException.ThrowIfNull(sourceCurrencyCode);

        var primaryExchangeRateCurrency = await GetCurrencyByIdAsync(_currencySettings.PrimaryExchangeRateCurrencyId) ?? throw new Exception("Primary exchange rate currency cannot be loaded");

        var result = amount;
        if (result == decimal.Zero || sourceCurrencyCode.Id == primaryExchangeRateCurrency.Id)
            return result;

        var exchangeRate = sourceCurrencyCode.Rate;
        if (exchangeRate == decimal.Zero)
            throw new NopException($"Exchange rate not found for currency [{sourceCurrencyCode.Name}]");
        result /= exchangeRate;

        return result;
    }

    /// <summary>
    /// Converts from primary exchange rate currency
    /// </summary>
    /// <param name="amount">Amount</param>
    /// <param name="targetCurrencyCode">Target currency code</param>

View on GitHub (pinned to 64bdf2ff08)

Solutions

  1. Re-point PrimaryExchangeRateCurrencyId to a valid, existing currency in Admin > Configuration > Currencies.
  2. Verify the currency row exists: check GetCurrencyByIdAsync(id) returns non-null in admin tooling.
  3. Add a startup guard that validates PrimaryExchangeRateCurrencyId resolves to a live currency.

Example fix

// before
var value = await _currencyService.ConvertToPrimaryExchangeRateCurrencyAsync(amount, source);

// after
if (await _currencyService.GetCurrencyByIdAsync(_currencySettings.PrimaryExchangeRateCurrencyId) is null)
    throw new InvalidOperationException("Primary exchange rate currency misconfigured.");
var value = await _currencyService.ConvertToPrimaryExchangeRateCurrencyAsync(amount, source);
Defensive patterns

Strategy: validation

Validate before calling

if (await _currencyService.GetCurrencyByIdAsync(_currencySettings.PrimaryExchangeRateCurrencyId) is null)
    throw new InvalidOperationException("Primary exchange rate currency misconfigured.");

Try / catch

try { await _currencyService.ConvertToPrimaryExchangeRateCurrencyAsync(amount, src); }
catch (Exception ex) when (ex.Message.Contains("Primary exchange rate currency cannot be loaded"))
{ /* alert ops to fix currency setting */ }

Prevention

When it happens

Trigger: Calling ConvertToPrimaryExchangeRateCurrencyAsync(amount, sourceCurrency) when PrimaryExchangeRateCurrencyId references a deleted/non-existent currency row.

Common situations: The primary exchange-rate currency record was deleted from the DB but the setting still points to its old Id; corrupted/inconsistent settings after a migration.

Related errors


AI-assisted analysis of nopSolutions/nopCommerce@64bdf2ff08 (2026-08-13). Data as JSON: /api/errors/bb476058a2b02b80. Report an issue: GitHub.