ory/hydra · error

errKeyNotFound

errKeyNotFound

Error message

key not found

What it means

decoderx's form decoder uses errKeyNotFound internally to signal that a required path/key was absent from the submitted form values. Callers like decodeURLValues' consumers check errors.Is(err, errKeyNotFound) to distinguish 'field missing' (often tolerated, e.g. partial PATCH forms) from genuine decode failures.

Source

Thrown at oryx/decoderx/http.go:82

	ParseErrorIgnoreConversionErrors parseErrorStrategy = iota + 1

	// ParseErrorUseEmptyValueOnConversionErrors will ignore any parse errors caused by strconv.Parse* and use the
	// default value of the type to be casted, e.g. float64(0), string("").
	//
	// If the JSON Schema defines `{"ratio": {"type": "number"}}` but `ratio=foobar` then field
	// `ratio` will receive the default value for the primitive type (here `0.0` for `number`).
	// If the destination struct is a `json.RawMessage`, then the output will be `{"ratio": 0.0}`.
	ParseErrorUseEmptyValueOnConversionErrors

	// ParseErrorReturnOnConversionErrors will abort and return with an error if strconv.Parse* returns
	// an error.
	//
	// If the JSON Schema defines `{"ratio": {"type": "number"}}` but `ratio=foobar` the parser aborts
	// and returns an error, here: `strconv.ParseFloat: parsing "foobar"`.
	ParseErrorReturnOnConversionErrors
)

var errKeyNotFound = errors.New("key not found")

// HTTPFormDecoder configures the HTTP decoder to only accept form-data
// (application/x-www-form-urlencoded, multipart/form-data)
func HTTPFormDecoder() HTTPDecoderOption {
	return func(o *httpDecoderOptions) {
		o.allowedContentTypes = []string{httpContentTypeMultipartForm, httpContentTypeURLEncodedForm}
	}
}

// HTTPJSONDecoder configures the HTTP decoder to only accept JSON data
// (application/json).
func HTTPJSONDecoder() HTTPDecoderOption {
	return func(o *httpDecoderOptions) {
		o.allowedContentTypes = []string{httpContentTypeJSON}
	}
}

// HTTPKeepRequestBody configures the HTTP decoder to allow other

View on GitHub (pinned to 4174065ffb)

Solutions

  1. Include the missing key in the submitted form data with a valid value.
  2. If the field is optional in your API, tolerate errKeyNotFound via errors.Is(err, decoderx.ErrKeyNotFound-style check) as the library does, and proceed with a zero value.
  3. Align the JSON schema field names with the actual form field names the client sends.
  4. Verify Content-Type is form-urlencoded or multipart so the form decoder actually parses the values.

Example fix

// before
if err := d.Decode(r, &update); err != nil { return err }
// after
if err := d.Decode(r, &update); err != nil && !errors.Is(err, errKeyNotFound) {
  return err
}
// missing keys then fall through to zero values
Defensive patterns

Strategy: type-guard

Validate before calling

// on the client, before submitting:
for _, f := range requiredFields {
  if r.Form.Get(f) == "" {
    return fmt.Errorf("missing required form field %q", f)
  }
}

Type guard

func isKeyNotFound(err error) bool { return errors.Is(err, errKeyNotFound) }

Try / catch

if err := decoder.Decode(r, &target); err != nil {
  if errors.Is(err, errKeyNotFound) {
    // optional field absent; proceed with zero value
  } else {
    return err
  }
}

Prevention

When it happens

Trigger: Posting application/x-www-form-urlencoded or multipart/form-data data to an endpoint whose HTTPFormDecoder schema expects a field, when the field is absent from the request body; the decodeForm/decodeURLValues path then produces errKeyNotFound, which the caller at http.go:382 may swallow for optional-field handling.

Common situations: Partial form submissions (PATCH where only some fields are sent), clients omitting optional checkboxes, renamed form fields not matching the JSON schema keys, or tests posting empty bodies.

Related errors


AI-assisted analysis of ory/hydra@4174065ffb (2026-09-03). Data as JSON: /api/errors/7e07e8b0c7acee55. Report an issue: GitHub.