GoogleCloudPlatform/microservices-demo · error · ErrMismatchingCurrency

mismatching currency codes

Error message

mismatching currency codes

What it means

Frontend copy of ErrMismatchingCurrency (src/frontend/money/money.go:31): money.Sum rejects adding two Money values whose CurrencyCode differs. Returned wherever frontend code sums prices in different currencies.

Source

Thrown at src/frontend/money/money.go:31

// limitations under the License.

package money

import (
	"errors"

	pb "github.com/GoogleCloudPlatform/microservices-demo/src/frontend/genproto"
)

const (
	nanosMin = -999999999
	nanosMax = +999999999
	nanosMod = 1000000000
)

var (
	ErrInvalidValue        = errors.New("one of the specified money values is invalid")
	ErrMismatchingCurrency = errors.New("mismatching currency codes")
)

// IsValid checks if specified value has a valid units/nanos signs and ranges.
func IsValid(m pb.Money) bool {
	return signMatches(m) && validNanos(m.GetNanos())
}

func signMatches(m pb.Money) bool {
	return m.GetNanos() == 0 || m.GetUnits() == 0 || (m.GetNanos() < 0) == (m.GetUnits() < 0)
}

func validNanos(nanos int32) bool { return nanosMin <= nanos && nanos <= nanosMax }

// IsZero returns true if the specified money value is equal to zero.
func IsZero(m pb.Money) bool { return m.GetUnits() == 0 && m.GetNanos() == 0 }

// IsPositive returns true if the specified money value is valid and is
// positive.

View on GitHub (pinned to 72ba613a05)

Solutions

  1. Convert operands to a common currency before Sum
  2. Guard with a currency-code equality check before summing
  3. Ensure cart item prices are re-converted when the user changes currency
  4. Audit catalog pricing for inconsistent currency codes

Example fix

// before
if l.GetCurrencyCode() != r.GetCurrencyCode() { return pb.Money{}, ErrMismatchingCurrency }
// after
if l.GetCurrencyCode() != r.GetCurrencyCode() {
    r, err = convertCurrency(r, l.GetCurrencyCode()); if err != nil { return pb.Money{}, err }
}
Defensive patterns

Strategy: validation

Validate before calling

if l.GetCurrencyCode() != r.GetCurrencyCode() {
	return errors.New("convert currencies before summing")
}
out, err := money.Sum(l, r)

Type guard

func currenciesMatch(l, r pb.Money) bool { return l.GetCurrencyCode() == r.GetCurrencyCode() }

Try / catch

out, err := money.Sum(l, r)
if errors.Is(err, money.ErrMismatchingCurrency) {
	converted, cerr := convert(r, l.GetCurrencyCode())
	if cerr != nil { return cerr }
	out, err = money.Sum(l, converted)
}

Prevention

When it happens

Trigger: Sum with operands having different currency codes, e.g. a cart item in USD combined with a price in EUR during cart/cost display or order placement.

Common situations: Missing currency conversion step before summation; user currency switched while cart holds prices in a previous currency; catalog data with inconsistent currency codes.

Related errors


AI-assisted analysis of GoogleCloudPlatform/microservices-demo@72ba613a05 (2026-09-02). Data as JSON: /api/errors/99c62258c05317c7. Report an issue: GitHub.