labstack/echo · error

failed to parse form values, key: %s, err: %w

Error message

failed to parse form values, key: %s, err: %w

What it means

Returned by echo.FormValues[T] (binder_generic.go:273-277) when c.FormValues() fails before the per-key slice parse can begin. Distinct from ErrNonExistentKey (returned when parsing succeeded but the key is absent).

Source

Thrown at binder_generic.go:276

	if len(values) == 0 {
		return defaultValue, nil
	}
	value := values[0]
	v, err := ParseValueOr[T](value, defaultValue, opts...)
	if err != nil {
		return v, NewBindingError(key, []string{value}, "form value", err)
	}
	return v, nil
}

// FormValues extracts and parses all values for a form values key as a slice.
// It returns the typed slice and an error if binding any value fails. Returns ErrNonExistentKey if parameter not found.
//
// See ParseValues for supported types and options
func FormValues[T any](c *Context, key string, opts ...any) ([]T, error) {
	formValues, err := c.FormValues()
	if err != nil {
		return nil, fmt.Errorf("failed to parse form values, key: %s, err: %w", key, err)
	}
	values, ok := formValues[key]
	if !ok {
		return nil, ErrNonExistentKey
	}
	result, err := ParseValues[T](values, opts...)
	if err != nil {
		return nil, NewBindingError(key, values, "form values", err)
	}
	return result, nil
}

// FormValuesOr extracts and parses all values for a form values key as a slice.
// Returns defaultValue if the parameter is not found.
// Returns an error only if parsing any value fails or form parsing errors occur.
//
// Example:
//

View on GitHub (pinned to 05489dc173)

Solutions

  1. Ensure a valid Content-Type and well-formed multipart/form body
  2. Increase multipart memory if parsing fails on size
  3. Check errors.Is(err, echo.ErrNonExistentKey) separately to differentiate missing-key from parse-failure

Example fix

// before
tags, err := echo.FormValues[string](c, "tags")
// after — distinguish a missing key from a bad body
tags, err := echo.FormValues[string](c, "tags")
if err != nil && !errors.Is(err, echo.ErrNonExistentKey) {
    return c.JSON(http.StatusBadRequest, map[string]string{"error": err.Error()})
}
Defensive patterns

Strategy: try-catch

Validate before calling

// For multipart bodies, reject early if ParseMultipartForm fails on size/boundary:
if c.Request().MultipartForm == nil {
    if err := c.Request().ParseMultipartForm(32 << 20); err != nil {
        return c.JSON(http.StatusBadRequest, map[string]string{"error": err.Error()})
    }
}

Try / catch

vs, err := echo.FormValues[string](c, "tags")
if err != nil {
    if errors.Is(err, echo.ErrNonExistentKey) {
        vs = nil
    } else {
        return c.JSON(http.StatusBadRequest, map[string]string{"error": err.Error()})
    }
}

Prevention

When it happens

Trigger: Calling FormValues[string](c, "tags") against a request whose multipart/form body cannot be parsed (bad boundary, wrong Content-Type, oversized).

Common situations: Malformed multipart on file-upload endpoints; wrong Content-Type; body-size limits.

Related errors


AI-assisted analysis of labstack/echo@05489dc173 (2026-08-04). Data as JSON: /data/errors/9ba9695006a9bfad.json. Report an issue: GitHub.