GoogleCloudPlatform/microservices-demo · error · ErrInvalidValue
one of the specified money values is invalid
Error message
one of the specified money values is invalid
What it means
The frontend carries an identical copy of the money helper (src/frontend/money/money.go), whose ErrInvalidValue is declared at money.go:30. It means a pb.Money operand failed IsValid: units/nanos signs mismatch or nanos out of range. Sum refuses arithmetic on malformed money.
Source
Thrown at src/frontend/money/money.go:30
// See the License for the specific language governing permissions and
// 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 isView on GitHub (pinned to 72ba613a05)
Solutions
- Validate with IsValid before summing
- Normalize nanos into units so the value satisfies signMatches && validNanos
- Fix the producer that emits invalid Money values
- Consider deduplicating the money package into a shared module to avoid drift
Example fix
// before
out, _ := money.Sum(invalidMoney, other)
// after
if !money.IsValid(invalidMoney) {
return pb.Money{}, fmt.Errorf("invalid money: %+v", invalidMoney)
}
out, err := money.Sum(invalidMoney, other) Defensive patterns
Strategy: validation
Validate before calling
if !money.IsValid(price) {
return errors.New("price failed IsValid: units/nanos sign mismatch or nanos out of range")
}
out, err := money.Sum(price, other) Type guard
func isValidMoney(m pb.Money) bool { return money.IsValid(m) } Try / catch
out, err := money.Sum(l, r)
if errors.Is(err, money.ErrInvalidValue) {
return fmt.Errorf("invalid money operand: %+v / %+v", l, r)
} Prevention
- Normalize nanos when converting from decimal/float sources
- Validate Money from other services before arithmetic
- Keep the frontend and checkoutservice money packages in sync (shared module)
When it happens
Trigger: Same as error 13: Sum called with units/nanos of opposite signs or |nanos| >= 1000000000, e.g. a Money built from un-normalized external input.
Common situations: Duplicated money package drift between frontend and checkoutservice; price values built by hand or converted from floats; protobuf Money produced by another service without validation.
Related errors
- one of the specified money values is invalid
- mismatching currency codes
- mismatching currency codes
- invalid validation error format
- InvalidCreditCard
AI-assisted analysis of GoogleCloudPlatform/microservices-demo@72ba613a05 (2026-09-02).
Data as JSON: /api/errors/276083859a6b032e.
Report an issue: GitHub.