---
title: Errors
description: Optional throwing behavior via throwOnError, backed by a shared ValidationError class.
type: package
package: "@zap-studio/validation"
---

`throwOnError` enables optional throwing, backed by a shared `ValidationError` class. Instead of dealing with each schema library's error shape, you catch one predictable error class and access normalized [Standard Schema](https://standardschema.dev) `issues`.

## Know When ValidationError Is Thrown

`ValidationError` is thrown only in throwing mode, by:

- `standardValidate(input, schema, { throwOnError: true })`
- `standardValidateSync(input, schema, { throwOnError: true })`
- validators from `createStandardValidator(schema)` called with `{ throwOnError: true }`
- validators from `createStandardValidatorSync(schema)` called with `{ throwOnError: true }`

When `throwOnError` is `false` or omitted, the helpers never throw for invalid input — they return the raw result with `issues` instead.

## Catch ValidationError

Import `ValidationError` from `validation` and check with `instanceof`.

```ts
import { standardValidate, ValidationError } from "@zap-studio/validation";
import { z } from "zod";

const userSchema = z.object({
  name: z.string(),
  age: z.number(),
});

try {
  const user = await standardValidate(input, userSchema, {
    throwOnError: true,
  });

  // use user
} catch (error) {
  if (error instanceof ValidationError) {
    console.error("Validation failed", error.issues);
    return;
  }

  throw error;
}
```

## Inspect the Error

`ValidationError` extends `Error` and exposes:

| Property  | Type                                | Description                                                                                      |
| --------- | ----------------------------------- | ------------------------------------------------------------------------------------------------ |
| `name`    | `string`                            | Always `"ValidationError"`.                                                                      |
| `issues`  | `readonly StandardSchemaV1.Issue[]` | The validation issues reported by the schema. Each issue has a `message` and an optional `path`. |
| `message` | `string`                            | A JSON string representation of `issues`, useful for logging.                                    |

```ts
if (error instanceof ValidationError) {
  for (const issue of error.issues) {
    console.error(issue.path, issue.message);
  }
}
```

## Handle Failures Without Exceptions

Use non-throwing mode when validation failures are expected and part of normal logic, such as form workflows where you return field errors instead of throwing.

```ts
import { standardValidate } from "@zap-studio/validation";
import { z } from "zod";

const emailSchema = z.object({
  email: z.email(),
});

const result = await standardValidate(formData, emailSchema);

if (result.issues) {
  return { ok: false, fieldErrors: result.issues };
}

return { ok: true, value: result.value };
```

As a rule of thumb:

- Use throwing mode when invalid input should interrupt control flow immediately, or when your layer already handles exceptions (API handlers, service boundaries).
- Use non-throwing mode when you want explicit branching on `issues` without exceptions.

## Handle Async Schema Errors

The sync helpers reject asynchronous schemas with errors that are **not** `ValidationError`:

- `standardValidateSync` throws a `TypeError` with the message `Async schemas are not supported by standardValidateSync`.
- Validators from `createStandardValidatorSync` throw an `Error` with the message `Async schemas are not supported by createStandardValidatorSync`, with the underlying `TypeError` as its `cause`.

These indicate a programming error (wrong helper for the schema), so let them propagate rather than catching them alongside validation failures. Switch to [`standardValidate`](/validation/async-validation) if the schema may validate asynchronously.

## See Also

- [Async Validation](/validation/async-validation)
- [Synchronous Validation](/validation/synchronous-validation)
