{"id":"9ba9695006a9bfad","repo":"labstack/echo","slug":"failed-to-parse-form-values-key-s-err-w","errorCode":null,"errorMessage":"failed to parse form values, key: %s, err: %w","messagePattern":"failed to parse form values, key: (.+?), err: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"binder_generic.go","lineNumber":276,"sourceCode":"\tif len(values) == 0 {\n\t\treturn defaultValue, nil\n\t}\n\tvalue := values[0]\n\tv, err := ParseValueOr[T](value, defaultValue, opts...)\n\tif err != nil {\n\t\treturn v, NewBindingError(key, []string{value}, \"form value\", err)\n\t}\n\treturn v, nil\n}\n\n// FormValues extracts and parses all values for a form values key as a slice.\n// It returns the typed slice and an error if binding any value fails. Returns ErrNonExistentKey if parameter not found.\n//\n// See ParseValues for supported types and options\nfunc FormValues[T any](c *Context, key string, opts ...any) ([]T, error) {\n\tformValues, err := c.FormValues()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse form values, key: %s, err: %w\", key, err)\n\t}\n\tvalues, ok := formValues[key]\n\tif !ok {\n\t\treturn nil, ErrNonExistentKey\n\t}\n\tresult, err := ParseValues[T](values, opts...)\n\tif err != nil {\n\t\treturn nil, NewBindingError(key, values, \"form values\", err)\n\t}\n\treturn result, nil\n}\n\n// FormValuesOr extracts and parses all values for a form values key as a slice.\n// Returns defaultValue if the parameter is not found.\n// Returns an error only if parsing any value fails or form parsing errors occur.\n//\n// Example:\n//","sourceCodeStart":258,"sourceCodeEnd":294,"githubUrl":"https://github.com/labstack/echo/blob/05489dc1730161df26b72d1ae2a3ba6fb8178fc7/binder_generic.go#L258-L294","documentation":"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).","triggerScenarios":"Calling FormValues[string](c, \"tags\") against a request whose multipart/form body cannot be parsed (bad boundary, wrong Content-Type, oversized).","commonSituations":"Malformed multipart on file-upload endpoints; wrong Content-Type; body-size limits.","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"],"exampleFix":"// before\ntags, err := echo.FormValues[string](c, \"tags\")\n// after — distinguish a missing key from a bad body\ntags, err := echo.FormValues[string](c, \"tags\")\nif err != nil && !errors.Is(err, echo.ErrNonExistentKey) {\n    return c.JSON(http.StatusBadRequest, map[string]string{\"error\": err.Error()})\n}","handlingStrategy":"try-catch","validationCode":"// For multipart bodies, reject early if ParseMultipartForm fails on size/boundary:\nif c.Request().MultipartForm == nil {\n    if err := c.Request().ParseMultipartForm(32 << 20); err != nil {\n        return c.JSON(http.StatusBadRequest, map[string]string{\"error\": err.Error()})\n    }\n}","typeGuard":null,"tryCatchPattern":"vs, err := echo.FormValues[string](c, \"tags\")\nif err != nil {\n    if errors.Is(err, echo.ErrNonExistentKey) {\n        vs = nil\n    } else {\n        return c.JSON(http.StatusBadRequest, map[string]string{\"error\": err.Error()})\n    }\n}","preventionTips":["Distinguish ErrNonExistentKey from real parse errors","Validate multipart boundaries client-side"],"tags":["binding","form"],"analyzedSha":"05489dc1730161df26b72d1ae2a3ba6fb8178fc7","analyzedAt":"2026-08-04T21:32:47.783Z","schemaVersion":2}