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
- Ensure a valid Content-Type and well-formed multipart/form body
- Increase multipart memory if parsing fails on size
- 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
- Distinguish ErrNonExistentKey from real parse errors
- Validate multipart boundaries client-side
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
- binding element must be a struct
- failed to parse form value, key: %s, err: %w
- query/param/form tags are not allowed with anonymous struct
- unknown type
- binding to multipart.FileHeader struct is not supported, use
AI-assisted analysis of labstack/echo@05489dc173 (2026-08-04).
Data as JSON: /data/errors/9ba9695006a9bfad.json.
Report an issue: GitHub.