---
title: "Validation"
description: "Hono provides a flexible validation middleware via the validator helper src/validator/index.ts:6, enabling developers to inspect, parse, and validate incoming request data across multiple targets i..."
last_updated: "2026-10-12T08:14:12.75099+00:00"
canonical_url: "https://www.doc0.dev/docs/552ca36e-f67e-41c3-a07a-def9bd9551b0/technical/helpers-and-tooling/validation"
---

<details>
<summary>Relevant source files</summary>

The following files were used as context for generating this wiki page:

- [src/middleware/ip-restriction/index.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/middleware/ip-restriction/index.ts)
- [src/validator/validator.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/validator/validator.ts)
- [src/utils/jwt/jwt.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/utils/jwt/jwt.ts)
- [src/request.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/request.ts)
- [src/adapter/aws-lambda/handler.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/adapter/aws-lambda/handler.ts)
- [src/validator/index.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/validator/index.ts)
- [src/types.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/types.ts)
- [src/validator/utils.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/validator/utils.ts)
- [src/utils/body.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/utils/body.ts)
- [src/middleware/jwt/jwt.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/middleware/jwt/jwt.ts)
- [src/utils/url.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/utils/url.ts)
- [src/utils/cookie.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/utils/cookie.ts)
- [src/middleware/language/language.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/middleware/language/language.ts)
- [src/client/fetch-result-please.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/client/fetch-result-please.ts)
- [src/context.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/context.ts)
- [src/jsx/utils.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/jsx/utils.ts)
- [src/jsx/dom/render.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/jsx/dom/render.ts)
- [src/middleware/method-override/index.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/middleware/method-override/index.ts)
- [src/helper/adapter/index.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/helper/adapter/index.ts)
- [src/middleware/body-limit/index.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/middleware/body-limit/index.ts)
- [src/client/utils.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/client/utils.ts)
- [src/utils/accept.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/utils/accept.ts)
- [src/helper/accepts/accepts.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/helper/accepts/accepts.ts)
- [src/utils/types.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/utils/types.ts)
- [src/utils/basic-auth.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/utils/basic-auth.ts)
- [package.json](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/package.json)
- [src/middleware/pretty-json/index.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/middleware/pretty-json/index.ts)
- [src/helper/cookie/index.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/helper/cookie/index.ts)
</details>

## Overview

Hono provides a flexible validation middleware via the `validator` helper src/validator/index.ts:6, enabling developers to inspect, parse, and validate incoming request data across multiple targets including JSON payloads, form data, query parameters, path parameters, headers, and cookies src/validator/validator.ts:9-12, 93-159. By integrating tightly with TypeScript type inference, the validation layer ensures that downstream handlers receive correctly typed input parameters while cleanly separating payload normalization and schema execution src/validator/validator.ts:64-82, 162-170. When validation fails, the system generates structured error responses or dispatches exceptions such as `HTTPException` to handle malformed inputs src/validator/validator.ts:101-102, 123-125.

Sources: [src/validator/index.ts:6](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/validator/index.ts#L6-L6), [src/validator/validator.ts:9-12](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/validator/validator.ts#L9-L12), [src/validator/validator.ts:64-82](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/validator/validator.ts#L64-L82), [src/validator/validator.ts:93-159](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/validator/validator.ts#L93-L159), [src/validator/validator.ts:162-170](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/validator/validator.ts#L162-L170), [src/validator/validator.ts:101-102](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/validator/validator.ts#L101-L102), [src/validator/validator.ts:123-125](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/validator/validator.ts#L123-L125)

## Validator middleware signature and targets

### Public Middleware API

The core validation mechanism is exposed through the `validator` helper function, which accepts a validation target and a validation callback function src/validator/validator.ts:46-88. The function signature leverages generic type parameters to enforce strict type safety between the requested validation target, the input data passed to the callback, and the inferred output type available to subsequent handlers src/validator/validator.ts:46-82.

```typescript
export const validator = <
  InputType,
  P extends string,
  M extends string,
  U extends ValidationTargetByMethod<M>,
  P2 extends string = P,
  // Capture the actual validation function as a type
  VF extends (
    value: unknown extends InputType ? ValidationTargets[U] : InputType,
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    c: Context<any, P2>
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
  ) => any = (
    value: unknown extends InputType ? ValidationTargets[U] : InputType,
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    c: Context<any, P2>
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
  ) => any,
  V extends {
    in: {
      [K in U]: K extends 'json'
        ? unknown extends InputType
          ? ExtractValidatorOutput<VF>
          : InputType
        : InferInput<ExtractValidatorOutput<VF>, K, FormValue>
    }
    out: { [K in U]: ExtractValidatorOutput<VF> }
  } = {
    in: {
      [K in U]: K extends 'json'
        ? unknown extends InputType
          ? ExtractValidatorOutput<VF>
          : InputType
        : InferInput<ExtractValidatorOutput<VF>, K, FormValue>
    }
    out: { [K in U]: ExtractValidatorOutput<VF> }
  },
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  E extends Env = any,
>(
  target: U,
  validationFunc: VF
): MiddlewareHandler<E, P, V, ExtractValidationResponse<VF>> => {
```
Sources: [src/validator/validator.ts:46-88](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/validator/validator.ts#L46-L88)

The validation function receives the extracted target value and the [execution context](https://www.doc0.dev/docs/552ca36e-f67e-41c3-a07a-def9bd9551b0/technical/core-engine/execution-context) src/validator/validator.ts:14-22. It may execute synchronously or asynchronously, returning either the transformed output value, a `TypedResponse`, or a direct `Response` instance src/validator/validator.ts:14-22.

```typescript
export type ValidationFunction<
  InputType,
  OutputType,
  E extends Env = {},
  P extends string = string,
> = (
  value: InputType,
  c: Context<E, P>
) => OutputType | TypedResponse | Promise<OutputType> | Promise<TypedResponse>

```
Sources: [src/validator/validator.ts:14-23](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/validator/validator.ts#L14-L23)

### Supported Validation Targets

Hono supports validation across six distinct request input targets src/validator/validator.ts:93-159. The allowed target keys are constrained based on the HTTP method of the route; specifically, `get` and `head` methods prohibit body-containing targets (`json` and `form`) src/validator/validator.ts:9-12.

```typescript
type ValidationTargetKeysWithBody = 'form' | 'json'
type ValidationTargetByMethod<M> = M extends 'get' | 'head' // GET and HEAD request must not have a body content.
  ? Exclude<keyof ValidationTargets, ValidationTargetKeysWithBody>
  : keyof ValidationTargets

```
Sources: [src/validator/validator.ts:9-13](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/validator/validator.ts#L9-L13)

| Target Key | Description | Allowed HTTP Methods |
| :--- | :--- | :--- |
| `json` | Request body parsed as JSON | All methods except `GET`, `HEAD` |
| `form` | Request body parsed as `FormData` or URL-encoded fields | All methods except `GET`, `HEAD` |
| `query` | URL query string parameters | All methods |
| `param` | Route path parameters | All methods |
| `header` | Request headers | All methods |
| `cookie` | Parsed request cookies | All methods |

Sources: [src/validator/validator.ts:9-12](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/validator/validator.ts#L9-L12), [src/validator/validator.ts:93-159](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/validator/validator.ts#L93-L159)

> [!NOTE]
> `get` and `head` routes restrict `ValidationTargetByMethod` to exclude body validation targets (`form` and `json`), preventing misuse on HTTP verbs that must not carry payload bodies.
> Sources: [src/validator/validator.ts:10-12](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/validator/validator.ts#L10-L12)

## Target extraction and decoding mechanisms

### Extraction and Parsing Call Sequences

When the `validator` middleware processes a `cookie` target, it dispatches execution through a structured utility chain to extract, parse, trim, and decode cookie values [[src/validator/validator.ts:157-159|src/validator/validator.ts:157-159], [src/helper/cookie/index.ts:27-48|src/helper/cookie/index.ts:27-48], [src/utils/cookie.ts:102-138|src/utils/cookie.ts:102-138], [src/utils/url.ts:81-93|src/utils/url.ts:81-93]]. 

The first call sequence executes: `validator` → `getCookie` → `parse` → `trimCookieWhitespace` [[src/validator/validator.ts:157-159|src/validator/validator.ts:157-159], [src/helper/cookie/index.ts:27-48|src/helper/cookie/index.ts:27-48], [src/utils/cookie.ts:102-138|src/utils/cookie.ts:102-138], [src/utils/cookie.ts:79-100|src/utils/cookie.ts:79-100]].

1. `validator` handles the target switch case for `cookie`, invoking `getCookie(c)` src/validator/validator.ts:157-159.
Sources: [src/validator/validator.ts:157-159](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/validator/validator.ts#L157-L159)
2. `getCookie` reads the `Cookie` header from `c.req.raw.headers`, and calls `parse(cookie)` if no specific key is requested src/helper/cookie/index.ts:27-48.
Sources: [src/helper/cookie/index.ts:27-48](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/helper/cookie/index.ts#L27-L48)
3. `parse` splits the cookie string by `;`, iterates through each pair, and isolates cookie names and values src/utils/cookie.ts:107-124.
Sources: [src/utils/cookie.ts:107-124](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/utils/cookie.ts#L107-L124)
4. `trimCookieWhitespace` strips leading and trailing spaces and tab characters (charCode `0x20` and `0x09`) from the parsed cookie name and value substrings [[src/utils/cookie.ts:79-100|src/utils/cookie.ts:79-100], [src/utils/cookie.ts:115|src/utils/cookie.ts:115], [src/utils/cookie.ts:124|src/utils/cookie.ts:124]].
Sources: [src/utils/cookie.ts:79-100](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/utils/cookie.ts#L79-L100), [src/utils/cookie.ts:115](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/utils/cookie.ts#L115), [src/utils/cookie.ts:124](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/utils/cookie.ts#L124)

The second call sequence executes: `validator` → `getCookie` → `parse` → `tryDecode` [[src/validator/validator.ts:157-159|src/validator/validator.ts:157-159], [src/helper/cookie/index.ts:27-48|src/helper/cookie/index.ts:27-48], [src/utils/cookie.ts:102-138|src/utils/cookie.ts:102-138], [src/utils/url.ts:81-93|src/utils/url.ts:81-93]].

1. `validator` dispatches to `getCookie(c)` src/validator/validator.ts:157-159.
Sources: [src/validator/validator.ts:157-159](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/validator/validator.ts#L157-L159)
2. `getCookie` retrieves the raw header and invokes `parse(cookie)` src/helper/cookie/index.ts:27-48.
Sources: [src/helper/cookie/index.ts:27-48](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/helper/cookie/index.ts#L27-L48)
3. `parse` validates cookie values against `validCookieValueRegEx` and checks for percent encoding src/utils/cookie.ts:128-130.
Sources: [src/utils/cookie.ts:128-130](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/utils/cookie.ts#L128-L130)
4. `tryDecode` attempts to decode percent-encoded cookie values using `decodeURIComponent_`, gracefully falling back to partial replacements if malformed sequences are encountered [[src/utils/cookie.ts:130|src/utils/cookie.ts:130], [src/utils/url.ts:81-93|src/utils/url.ts:81-93]].
Sources: [src/utils/cookie.ts:130](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/utils/cookie.ts#L130), [src/utils/url.ts:81-93](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/utils/url.ts:81-93)

```mermaid
sequenceDiagram
    participant validator as validator.ts
    participant cookieHelper as helper/cookie/index.ts
    participant cookieUtil as utils/cookie.ts
    participant urlUtil as utils/url.ts

    validator->>cookieHelper: getCookie(c)
    cookieHelper->>cookieUtil: parse(cookie, finalKey?)
    cookieUtil->>cookieUtil: trimCookieWhitespace(substring)
    cookieUtil->>urlUtil: tryDecode(cookieValue, decodeURIComponent_)
```
Sources: [src/validator/validator.ts:157-159](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/validator/validator.ts#L157-L159), [src/helper/cookie/index.ts:27-48](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/helper/cookie/index.ts#L27-L48), [src/utils/cookie.ts:79-138](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/utils/cookie.ts#L79-L138), [src/utils/url.ts:81-93](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/utils/url.ts:81-93)

### Target Extraction Implementations

Non-cookie targets extract request data directly from the context request wrapper inside the `validator` switch statement src/validator/validator.ts:93-160. Query parameters map multi-value fields when query arrays exceed a length of one src/validator/validator.ts:144-150.

```typescript
  case 'query':
    value = Object.fromEntries(
      Object.entries(c.req.queries()).map(([k, v]) => {
        return v.length === 1 ? [k, v[0]] : [k, v]
      })
    )
    break
  case 'param':
    value = c.req.param() as Record<string, string>
    break
  case 'header':
    value = c.req.header()
    break
  case 'cookie':
    value = getCookie(c)
    break
}
```
Sources: [src/validator/validator.ts:144-160](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/validator/validator.ts#L144-L160)

> [!WARNING]
> When parsing cookies or query parameters, `tryDecode` catches decoding exceptions on malformed percent-encoding and decodes valid segments independently rather than failing the entire request src/utils/url.ts:81-93.
> Sources: [src/utils/url.ts:81-93](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/utils/url.ts:81-93)

> [!NOTE]
> `getQueryStrings` scans the request URL starting at index 8 to locate query parameters, returning an empty string if no query indicator `?` is present src/utils/url.ts:136-139.
> Sources: [src/utils/url.ts:136-139](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/utils/url.ts:136-139)

## Payload parsing and form normalization

### Processing JSON and Form Payloads

When the validator processes a request with target `json` or `form`, it first inspects the `Content-Type` header against explicit regular expression patterns defined in `src/validator/validator.ts`. JSON payloads require a content type matching `jsonRegex`, which supports standard application/json types along with structured syntax suffixes. Form payloads accept content types matching either `multipartRegex` or `urlencodedRegex`.

```typescript
const jsonRegex = /^application\/([a-z-\.]+\+)?json(;\s*[a-zA-Z0-9\-]+\=([^;]+))*$/
const multipartRegex = /^multipart\/form-data(;\s?boundary=[a-zA-Z0-9'"()+_,\-./:=?]+)?$/
const urlencodedRegex = /^application\/x-www-form-urlencoded(;\s*[a-zA-Z0-9\-]+\=([^;]+))*$/
```
Sources: [src/validator/validator.ts:24-26](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/validator/validator.ts#L24-L26)

If a request specifies a `json` target but supplies a malformed body or an unmatching content type, `c.req.json()` throws an error caught by the validator, which then throws an `HTTPException` with status code `400` and message `'Malformed JSON in request body'`.

```typescript
try {
  value = await c.req.json()
} catch {
  const message = 'Malformed JSON in request body'
  throw new HTTPException(400, { message })
}
```
Sources: [src/validator/validator.ts:98-103](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/validator/validator.ts#L28-L103)

> [!WARNING]
> Form body parsing checks `c.req.bodyCache.formData` before consuming the stream. If absent, it reads the request as an `ArrayBuffer` and transforms it via `bufferToFormData`, caching the resulting `FormData` instance on the request object.
> Sources: [src/validator/validator.ts:113-127](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/validator/validator.ts#L113-L127)

### FormData Normalization and Key Handling

The form target normalizes raw `FormData` entries into a structured record using a null-prototype object. During iteration over form fields, keys ending with `[]` or keys encountering duplicate entries are accumulated into arrays, while single entries populate scalar string or `File` values.

```typescript
const form: BodyData<{ all: true }> = Object.create(null)
formData.forEach((value, key) => {
  if (key.endsWith('[]')) {
    ;((form[key] ??= []) as unknown[]).push(value)
  } else if (Array.isArray(form[key])) {
    ;(form[key] as unknown[]).push(value)
  } else if (Object.hasOwn(form, key)) {
    form[key] = [form[key] as string | File, value]
  } else {
    form[key] = value
  }
})
```
Sources: [src/validator/validator.ts:129-140](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/validator/validator.ts#L129-L140)

For broader utility usage outside validation, standalone body parsing via `parseBody` supports configuration options defined in `ParseBodyOptions`. These options control array expansion and dot-notation nesting.

| Option | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `all` | `boolean` | `false` | Determines whether all fields with multiple values should be parsed as arrays |
| `dot` | `boolean` | `false` | Determines whether fields with dot notation should be parsed as nested objects |

Sources: [src/utils/body.ts:43-74](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/utils/body.ts#L43-L74)

> [!CAUTION]
> Nested form value parsing guards against prototype pollution attacks by explicitly ignoring any key paths containing `__proto__`.
> Sources: [src/utils/body.ts:211-213](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/utils/body.ts#L211-L213)

## Schema validation and execution pipeline

### Executing Validation Functions

Once the input data is extracted and parsed according to the target type, the validator invokes the provided `validationFunc` callback with the assembled value and the active `Context` instance. This function can be synchronous or asynchronous, returning either a transformed output object, a `TypedResponse`, a raw `Response`, or a Promise resolving to any of these types.

```typescript
export type ValidationFunction<
  InputType,
  OutputType,
  E extends Env = {},
  P extends string = string,
> = (
  value: InputType,
  c: Context<E, P>
) => OutputType | TypedResponse | Promise<OutputType> | Promise<TypedResponse>

```
Sources: [src/validator/validator.ts:14-23](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/validator/validator.ts#L14-L23)

```typescript
const res = await validationFunc(value as never, c as never)

```
Sources: [src/validator/validator.ts:162-163](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/validator/validator.ts#L162-L163)

> [!NOTE]
> The validation function signature accepts `unknown` inputs for JSON targets or infers input properties based on third-party schema definitions when using utility helpers.
> Sources: [src/validator/validator.ts:53-63](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/validator/validator.ts#L53-L63)

### Handling Validation Outputs

After the validation callback completes, the execution pipeline inspects the returned result to determine whether to short-circuit the request or proceed down the middleware chain. If the result is an instance of `Response`, the validator immediately returns that response, bypassing subsequent middleware handlers.

```typescript
if (res instanceof Response) {
  return res as ExtractValidationResponse<VF>
}
```
Sources: [src/validator/validator.ts:164-166](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/validator/validator.ts#L164-L166)

If the validation function returns a transformed output rather than a response object, the validator stores the validated data in the request context using `c.req.addValidatedData(target, res)` and delegates control to the next handler by calling `await next()`.

```typescript
c.req.addValidatedData(target, res as never)

return (await next()) as ExtractValidationResponse<VF>
```
Sources: [src/validator/validator.ts:168-170](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/validator/validator.ts#L168-L170)

> [!TIP]
> The `ExtractValidatorOutput` conditional type helper unwraps promises and strips out `Response` or `TypedResponse` union constituents, ensuring type inference correctly isolates the parsed data payload from error responses.
> Sources: [src/validator/validator.ts:175-185](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/validator/validator.ts#L175-L185)

## Error response and exception dispatching

### Handling Request Payload Exceptions

When parsing incoming request bodies such as JSON or multipart form data, malformed payloads trigger explicit HTTP exceptions that short-circuit request handling. If JSON parsing fails due to syntax errors, the validator catches the exception and raises an `HTTPException` with status code `400` and a descriptive error message.

```typescript
try {
  value = await c.req.json()
} catch {
  const message = 'Malformed JSON in request body'
  throw new HTTPException(400, { message })
}
```
Sources: [src/validator/validator.ts:98-103](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/validator/validator.ts#L98-L103)

Similarly, failures encountered during `FormData` buffer conversion catch the underlying error and construct a `400` status exception combining a base message with the original error details.

```typescript
try {
  const arrayBuffer = await c.req.arrayBuffer()
  formData = await bufferToFormData(arrayBuffer, contentType)
  c.req.bodyCache.formData = formData
} catch (e) {
  let message = 'Malformed FormData request.'
  message += e instanceof Error ? ` ${e.message}` : ` ${String(e)}`
  throw new HTTPException(400, { message })
}
```
Sources: [src/validator/validator.ts:118-126](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/validator/validator.ts#L118-L126)

> [!CAUTION]
> Uncaught exceptions during body consumption throw standardized `HTTPException` instances with HTTP status `400`, preventing internal server crashes from malformed client input.
> Sources: [src/validator/validator.ts:101-102](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/validator/validator.ts#L101-L102), [src/validator/validator.ts:125-125](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/validator/validator.ts#L125-L125)

### Custom Response Dispatching

Validation functions can handle failure conditions directly by returning a `Response` or `TypedResponse` instance instead of validated data. When the execution pipeline evaluates the result of the validation callback and detects a `Response` object, it immediately returns that response to the client.

```typescript
if (res instanceof Response) {
  return res as ExtractValidationResponse<VF>
}
```
Sources: [src/validator/validator.ts:164-166](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/validator/validator.ts#L164-L166)

This mechanism allows schema validation libraries or custom callback handlers to dispatch validation error codes, custom JSON error payloads, or redirection responses without throwing unhandled exceptions.

> [!TIP]
> Returning a `Response` from a validation function bypasses `c.req.addValidatedData` and immediately halts middleware execution, returning the custom response directly.
> Sources: [src/validator/validator.ts:164-166](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/validator/validator.ts#L164-L166)

## Related

- [RPC Client](https://www.doc0.dev/docs/552ca36e-f67e-41c3-a07a-def9bd9551b0/technical/helpers-and-tooling/rpc-client)
- [Execution Context](https://www.doc0.dev/docs/552ca36e-f67e-41c3-a07a-def9bd9551b0/technical/core-engine/execution-context)


## Sitemap

See the full [sitemap](https://www.doc0.dev/docs/552ca36e-f67e-41c3-a07a-def9bd9551b0/llms.txt) for all pages in this wiki.
