GoogleCloudPlatform/microservices-demo · warning

%s

Error message

%s

What it means

ValidationErrorResponse in src/frontend/validator/validator.go converts go-playground/validator.ValidationErrors into a human-readable message, building one "Field '<field>' is invalid: <tag>" line per violation and returning fmt.Errorf("%s", msg). If the error cannot be asserted to validator.ValidationErrors it returns errors.New("invalid validation error format"). The returned message aggregates every failed field validation from form parsing (add-to-cart, place order, set currency).

Source

Thrown at src/frontend/validator/validator.go:82

func (po *PlaceOrderPayload) Validate() error {
	return validate.Struct(po)
}

func (sc *SetCurrencyPayload) Validate() error {
	return validate.Struct(sc)
}

// Reusable error response function.
func ValidationErrorResponse(err error) error {
	validationErrs, ok := err.(validator.ValidationErrors)
	if !ok {
		return errors.New("invalid validation error format")
	}
	var msg string
	for _, err := range validationErrs {
		msg += fmt.Sprintf("Field '%s' is invalid: %s\n", err.Field(), err.Tag())
	}
	return fmt.Errorf("%s", msg)
}

View on GitHub (pinned to 72ba613a05)

Solutions

  1. Read the returned message — each line names the field and the failed tag; fix the client to send valid values
  2. Ensure the HTML form includes all fields required by the validator struct tags
  3. Add client-side (HTML5 required/pattern) validation to catch bad input before submit
  4. Check that struct tags match the current form field names after refactors
  5. Handle the error as a 4xx (bad request) rendered to the user, not a server fault

Example fix

// before
return fmt.Errorf("%s", msg)
// after
msg = strings.TrimSuffix(msg, "\n")
return fmt.Errorf("invalid input: %s", msg)
Defensive patterns

Strategy: validation

Validate before calling

qty := r.FormValue("quantity")
n, err := strconv.Atoi(qty)
if err != nil || n < 1 || n > 100 {
    http.Error(w, "invalid quantity", http.StatusBadRequest)
    return
}

Type guard

func isValidationError(err error) (validator.ValidationErrors, bool) {
    var ve validator.ValidationErrors
    if errors.As(err, &ve) {
        return ve, true
    }
    return nil, false
}

Try / catch

if err := validator.Struct(form); err != nil {
    if ve, ok := isValidationError(err); ok {
        http.Error(w, ValidationErrorResponse(ve).Error(), http.StatusBadRequest)
        return
    }
    http.Error(w, "invalid input", http.StatusBadRequest)
}

Prevention

When it happens

Trigger: addToCartHandler, placeOrderHandler, or setCurrencyHandler parse a form/struct whose fields fail go-playground/validator tag rules (e.g. missing/invalid quantity, currency code, product id); ValidationErrorResponse then formats the ValidationErrors.

Common situations: User submits the form with empty or malformed fields; a bot or curl request posts without required form values; template/form field name changes desync the struct tags; currency code not matching expected enum/oneof tag.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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