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.
Formatting
Signature
type CheckHook = (issue: Filter) => string | undefined;defaultCheckHook
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;defaultLeafHook
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;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
makeFormatterDefault— creates aFormatter<string>makeFormatterStandardSchemaV1— creates aFormatter<StandardSchemaV1.FailureResult>
Signature
interface Formatter<out Format> extends Formatter<Issue, Format> {
(value: Issue): Format;
}Callback type used to format Leaf issues into strings.
When to use
Use when customizing how makeFormatterStandardSchemaV1 renders terminal issues.
See
defaultLeafHook— the built-in implementationLeaf— the union of terminal issue types
Signature
type LeafHook = (issue: Leaf) => string;makeFormatterDefault
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
makeFormatterStandardSchemaV1— produces Standard Schema V1 format insteadFormatter
Signature
declare function makeFormatterDefault(): Formatter<string>;makeFormatterStandardSchemaV1
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
makeFormatterDefault— produces a plain string insteadLeafHookCheckHook
Signature
declare function makeFormatterStandardSchemaV1(options?: {
readonly checkHook?: CheckHook;
readonly leafHook?: LeafHook;
}): Formatter<FailureResult>;Guards
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
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
Signature
declare class AnyOf extends Base {
constructor(ast: Union, issues: readonly Array<Issue>);
readonly _tag: "AnyOf";
readonly ast: Union;
readonly issues: readonly Array<Issue>;
}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
Signature
declare class Composite extends Base {
constructor(ast: AST, issues: readonly [Issue, Issue]);
readonly _tag: "Composite";
readonly ast: AST;
readonly issues: readonly [Issue, Issue];
}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
Signature
declare class Encoding extends Base {
constructor(ast: AST, issue: Issue);
readonly _tag: "Encoding";
readonly ast: AST;
readonly issue: Issue;
}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
Signature
declare class Filter extends Base {
constructor(filter: Filter<any>, issue: Issue);
readonly _tag: "Filter";
readonly filter: Filter<unknown>;
readonly issue: Issue;
}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
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
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 entirelyFilter— 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;
}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;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
Signature
type Leaf = InvalidType | InvalidValue | MissingKey | UnexpectedKey | Forbidden | OneOf;MissingKey
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 pathUnexpectedKey— 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;
}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>;
}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>;
}UnexpectedKey
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;
}
Callback type used to format Filter issues into strings.
When to use
Use when customizing how makeFormatterStandardSchemaV1 renders filter failures.
Details
- Returns
stringto override the message, orundefinedto fall back to the default formatting. - Built-in issues have noactualfield.See
defaultCheckHook— the built-in implementationFilter— the issue type this hook formats