nopSolutions/nopCommerce · error · NopException

Exchange rate not found for currency [{sourceCurrencyCode.Na

Error message

Exchange rate not found for currency [{sourceCurrencyCode.Name}]

What it means

Thrown by ConvertToPrimaryExchangeRateCurrencyAsync as a NopException when sourceCurrencyCode.Rate equals decimal.Zero. The conversion divides by the source currency's Rate, so a zero rate would either divide-by-zero or yield nonsense; the guard rejects it explicitly.

Source

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

    /// <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>
    /// <returns>
    /// A task that represents the asynchronous operation
    /// The task result contains the converted value
    /// </returns>
    public virtual async Task<decimal> ConvertFromPrimaryExchangeRateCurrencyAsync(decimal amount, Currency targetCurrencyCode)
    {
        ArgumentNullException.ThrowIfNull(targetCurrencyCode);

View on GitHub (pinned to 64bdf2ff08)

Solutions

  1. Set a non-zero Rate for the source currency in Admin > Configuration > Currencies (or trigger a live-rate refresh).
  2. Validate currency.Rate > 0 before invoking the conversion.
  3. Skip conversion when amount is zero (the method already short-circuits this) — but fix the underlying rate for non-zero amounts.

Example fix

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

// after
if (sourceCurrency.Rate == decimal.Zero)
    throw new InvalidOperationException($"Currency '{sourceCurrency.Name}' has no exchange rate set.");
var value = await _currencyService.ConvertToPrimaryExchangeRateCurrencyAsync(amount, sourceCurrency);
Defensive patterns

Strategy: validation

Validate before calling

if (sourceCurrency.Rate == decimal.Zero)
    throw new InvalidOperationException($"Currency '{sourceCurrency.Name}' has no rate.");

Type guard

static bool HasRate(Currency c) => c is not null && c.Rate != decimal.Zero;

Try / catch

try { await _currencyService.ConvertToPrimaryExchangeRateCurrencyAsync(amount, src); }
catch (NopException ex) when (ex.Message.Contains("Exchange rate not found"))
{ _logger.LogWarning(ex, "Missing rate; skipping conversion."); }

Prevention

When it happens

Trigger: Calling ConvertToPrimaryExchangeRateCurrencyAsync with a Currency whose Rate property is 0 (unset). The branch only triggers when the source differs from the primary currency and amount is non-zero.

Common situations: A currency was added but its exchange rate never populated; an admin reset rates; a manual rate entry was cleared; import job wrote Rate=0.

Related errors


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