Skip to content

SchemaIssue

Describes problems found while decoding, encoding, or checking data with schemas.

An Issue records what failed and, for nested data, where the failure happened. The Schema system uses these values for missing keys, unexpected keys, invalid types, invalid values, failed filters, failed transformations, and alternatives that did not match. This module also formats issues.

21 exports Added in v3.10.0 Source

Formatting

CheckHook type

Added in v4.0.0 Source

Callback type used to format Filter issues into strings.

When to use

Use when customizing how makeFormatterStandardSchemaV1 renders filter failures.

Details

- Returns string to override the message, or undefined to fall back to the default formatting. - Built-in issues have no actual field.

See

Signature

type CheckHook = (issue: Filter) => string | undefined;

Returns the built-in CheckHook used by default formatters.

When to use

Use as the default filter renderer when customizing only the LeafHook.

Details

- Looks for a message annotation on the inner issue first, then on the filter itself. - Returns undefined when no annotation is found, causing the formatter to fall back to "Expected <filter>".

See

Signature

declare const defaultCheckHook: CheckHook;

Returns the built-in LeafHook used by default formatters.

When to use

Use as the default leaf renderer when customizing only the CheckHook.

Details

- Checks for a message annotation first; returns it if present. - Otherwise generates a default message per _tag: - InvalidType"Expected <type>" - InvalidValue"Expected a valid value" - MissingKey"Missing key" - UnexpectedKey"Expected no excess property" - Forbidden"Forbidden operation" - OneOf"Expected exactly one member to match"

See

Signature

declare const defaultLeafHook: LeafHook;

Formatter interface

Added in v4.0.0 Source

A function type that converts an Issue into a formatted representation. Specialisation of the generic Formatter from Formatter.ts with Value fixed to Issue.

See

Signature

interface Formatter<out Format> extends Formatter<Issue, Format> {
  (value: Issue): Format;
}

LeafHook type

Added in v4.0.0 Source

Callback type used to format Leaf issues into strings.

When to use

Use when customizing how makeFormatterStandardSchemaV1 renders terminal issues.

See

Signature

type LeafHook = (issue: Leaf) => string;

Creates a Formatter that converts an Issue into a human-readable multi-line string.

When to use

Use when you need to format a SchemaIssue.Issue as error messages for logging, CLI output, or developer-facing diagnostics.

Details

This is the default formatter used by SchemaIssue.toString().

- Flattens the issue tree into { message, path } entries using defaultLeafHook and defaultCheckHook. - Each entry is rendered as "<message>" or "<message>\n at <path>". - Multiple entries are joined with newlines.

See

Signature

declare function makeFormatterDefault(): Formatter<string>;

Creates a Formatter that produces a StandardSchemaV1.FailureResult.

When to use

Use when you need schema parse errors in [Standard Schema V1](https://github.com/standard-schema/standard-schema) format, optionally customizing leaf or check issue rendering.

Details

- Returns a Formatter<StandardSchemaV1.FailureResult>. - Each leaf issue is flattened into { message, path } entries. - Pointer paths are accumulated to produce full property paths. - Falls back to defaultLeafHook / defaultCheckHook when no hooks are provided.

See

Signature

declare function makeFormatterStandardSchemaV1(options?: {
  readonly checkHook?: CheckHook;
  readonly leafHook?: LeafHook;
}): Formatter<FailureResult>;

Guards

isIssue

Added in v4.0.0 Source

Returns true if the given value is an Issue.

When to use

Use when you need to narrow an unknown value to Issue in error-handling code, such as distinguishing an Issue from other error types in a catch-all handler.

Details

- Checks for the internal TypeId brand on the value.

See

Signature

declare function isIssue(u: unknown): u is Issue;

Models

AnyOf

Added in v4.0.0 Source

Represents a schema issue produced when a value does not match *any* member of a union schema.

When to use

Use when you need to inspect which union members were attempted and why each failed.

Details

- ast is the Union AST node. - issues contains the per-member failures.

Gotchas

issues is empty when no union member was applicable. In that case, the default formatter reports the expected type for the union.

See

  • OneOf — the opposite: *too many* members matched
  • Composite — groups multiple issues under a non-union schema

Signature

declare class AnyOf extends Base {
  constructor(ast: Union, issues: readonly Array<Issue>);
  readonly _tag: "AnyOf";
  readonly ast: Union;
  readonly issues: readonly Array<Issue>;
}

Composite

Added in v3.10.0 Source

Represents a schema issue that groups multiple child issues under a single schema node.

When to use

Use when you need to walk the issue tree for struct/tuple schemas that collect all field errors rather than failing on the first.

Details

- issues is a non-empty readonly array (at least one child). - Formatters flatten Composite by recursing into each child.

See

  • AnyOf — used for union no-match errors (similar but different semantics)
  • Pointer — adds path context to individual issues

Signature

declare class Composite extends Base {
  constructor(ast: AST, issues: readonly [Issue, Issue]);
  readonly _tag: "Composite";
  readonly ast: AST;
  readonly issues: readonly [Issue, Issue];
}

Encoding

Added in v4.0.0 Source

Represents a schema issue produced when a schema transformation (encode/decode step) fails.

When to use

Use when you need to inspect failures from Schema.decodeTo / Schema.encodeTo transformations.

Details

- ast is the AST node for the transformation that failed. - issue is the inner issue describing the failure.

See

  • Filter — failure from a refinement check (not a transformation)
  • Composite — multiple issues from a single schema node

Signature

declare class Encoding extends Base {
  constructor(ast: AST, issue: Issue);
  readonly _tag: "Encoding";
  readonly ast: AST;
  readonly issue: Issue;
}

Filter

Added in v4.0.0 Source

Represents a schema issue produced when a schema filter (refinement check) fails.

When to use

Use when you need to inspect a schema issue that records which refinement check rejected the value.

Details

- filter is the AST filter node that produced this issue. - issue is the inner issue describing the failure reason.

See

  • Leaf — terminal issue types that commonly appear as the inner issue
  • CheckHook — formatter hook for Filter issues

Signature

declare class Filter extends Base {
  constructor(filter: Filter<any>, issue: Issue);
  readonly _tag: "Filter";
  readonly filter: Filter<unknown>;
  readonly issue: Issue;
}

Forbidden

Added in v3.10.0 Source

Represents a schema issue produced when a forbidden operation is encountered during parsing, such as an asynchronous Effect running inside Schema.decodeUnknownSync.

When to use

Use when you need to detect that a schema requires async execution but was run synchronously.

Details

- annotations optionally carries a message string. - The default formatter renders this as "Forbidden operation".

See

  • InvalidValue — for value-constraint failures (not operation failures)

Signature

declare class Forbidden extends Base {
  constructor(annotations: Issue | undefined);
  readonly _tag: "Forbidden";
  readonly annotations: Issue | undefined;
}

InvalidType

Added in v4.0.0 Source

Represents a schema issue produced when the runtime type of the input does not match the type expected by the schema.

When to use

Use when you need to detect basic type mismatches, such as a wrong primitive or null where an object was expected.

Details

- ast is the schema node that expected a different type. - The default formatter renders this as "Expected <type>".

See

  • InvalidValue — the input has the right type but fails a value constraint

Signature

declare class InvalidType extends Base {
  constructor(ast: AST);
  readonly _tag: "InvalidType";
  readonly ast: AST;
}

InvalidValue

Added in v4.0.0 Source

Represents a schema issue produced when the input has the correct type but its value violates a constraint (e.g. a string that is too short, a number out of range).

When to use

Use when you need to detect constraint violations from Schema.filter, Schema.minLength, Schema.greaterThan, or similar checks.

Details

- annotations optionally carries a message string for formatting. - The default formatter renders this as "Expected a valid value" unless a custom message annotation is provided.

See

  • InvalidType — the input has the wrong type entirely
  • Filter — composite wrapper when a schema filter produces this issue

Signature

declare class InvalidValue extends Base {
  constructor(annotations?: Issue);
  readonly _tag: "InvalidValue";
  readonly annotations: Issue | undefined;
}

Issue type

Added in v4.0.0 Source

The root discriminated union of all validation error nodes.

When to use

Use when typing the error channel in Effect<A, Issue, R> results from schema parsing, or when writing custom formatters or issue-tree walkers.

Details

Every node has a _tag field for pattern-matching. The union includes both terminal Leaf types and composite types that wrap inner issues: Filter, Encoding, Pointer, Composite, AnyOf. All Issue instances have a toString() that delegates to the default formatter, so String(issue) produces a human-readable message. Built-in issues have no actual field, and built-in messages do not include the rejected value. This is not a general sanitization boundary: paths, ASTs, union successes, and custom annotations or messages are preserved as supplied and remain the caller's responsibility.

See

Signature

type Issue = Leaf | Filter | Encoding | Pointer | Composite | AnyOf;

Leaf type

Added in v4.0.0 Source

Union of all terminal (leaf) issue types that have no inner Issue children.

When to use

Use when constraining formatter hooks to only handle terminal nodes or when pattern matching on the _tag of an issue and only leaf nodes matter.

Details

Members: InvalidType, InvalidValue, MissingKey, UnexpectedKey, Forbidden, OneOf.

See

  • Issue — the full union including composite nodes
  • LeafHook — formatter hook that operates on Leaf values

Signature

type Leaf = InvalidType | InvalidValue | MissingKey | UnexpectedKey | Forbidden | OneOf;

MissingKey

Added in v4.0.0 Source

Represents a schema issue produced when a required key or tuple index is missing from the input.

When to use

Use when you need to detect absent fields in struct/tuple validation.

Details

- annotations may contain a custom messageMissingKey for formatting.

See

  • Pointer — wraps this issue with the missing key's path
  • UnexpectedKey — the opposite case (extra key present)

Signature

declare class MissingKey extends Base {
  constructor(annotations: Key<unknown> | undefined);
  readonly _tag: "MissingKey";
  readonly annotations: Key<unknown> | undefined;
}

OneOf

Added in v4.0.0 Source

Represents a schema issue produced when a value matches *multiple* members of a union that is configured to allow exactly one match (oneOf mode).

When to use

Use when you need to detect ambiguous union matches when oneOf validation is enabled.

Details

- ast is the Union AST node. - successes lists the AST nodes of each member that accepted the input. - The default formatter renders this as "Expected exactly one member to match".

See

  • AnyOf — the opposite: *no* members matched

Signature

declare class OneOf extends Base {
  constructor(ast: Union, successes: readonly Array<AST>);
  readonly _tag: "OneOf";
  readonly ast: Union;
  readonly successes: readonly Array<AST>;
}

Pointer

Added in v3.10.0 Source

Wraps an inner Issue with a property-key path, indicating *where* in a nested structure the error occurred.

When to use

Use when you need to walk the issue tree to accumulate path segments for error reporting.

Details

- path is an array of property keys (strings, numbers, or symbols). - Formatters concatenate nested Pointer paths into a single path like ["a"]["b"][0].

See

  • Composite — groups multiple issues under one schema node

Signature

declare class Pointer extends Base {
  constructor(path: readonly Array<PropertyKey>, issue: Issue);
  readonly _tag: "Pointer";
  readonly issue: Issue;
  readonly path: readonly Array<PropertyKey>;
}

Represents a schema issue produced when an input object or tuple contains a key/index not declared by the schema.

When to use

Use when you need to detect excess properties during strict struct/tuple validation.

Details

- ast is the schema that was being validated against. - annotations on ast may contain a custom messageUnexpectedKey. - The default formatter renders this as "Expected no excess property".

See

  • MissingKey — the opposite case (required key absent)
  • Pointer — wraps this issue with the unexpected key's path

Signature

declare class UnexpectedKey extends Base {
  constructor(ast: AST);
  readonly _tag: "UnexpectedKey";
  readonly ast: AST;
}