SchemaIssue.ts
SchemaIssue.ts overview
Section titled “SchemaIssue.ts overview”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 and
supports redaction for sensitive values.
Since v4.0.0
Exports Grouped by Category
Section titled “Exports Grouped by Category”- Formatter
- getters
- guards
- models
Formatter
Section titled “Formatter”CheckHook (type alias)
Section titled “CheckHook (type alias)”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.
See
defaultCheckHook— the built-in implementationFilter— the issue type this hook formats
Signature
type CheckHook = (issue: Filter) => string | undefinedSince v4.0.0
Formatter (interface)
Section titled “Formatter (interface)”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
export interface Formatter<out Format> extends FormatterI<Issue, Format> {}Since v4.0.0
LeafHook (type alias)
Section titled “LeafHook (type alias)”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) => stringSince v4.0.0
defaultCheckHook
Section titled “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
messageannotation on the inner issue first, then on the filter itself. - Returns
undefinedwhen no annotation is found, causing the formatter to fall back to"Expected <filter>, got <actual>".
See
CheckHookmakeFormatterStandardSchemaV1
Signature
declare const defaultCheckHook: CheckHookSince v4.0.0
defaultLeafHook
Section titled “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
messageannotation first; returns it if present. - Otherwise generates a default message per
_tag:InvalidType→"Expected <type>, got <actual>"InvalidValue→"Invalid data <actual>"MissingKey→"Missing key"UnexpectedKey→"Unexpected key with value <actual>"Forbidden→"Forbidden operation"OneOf→"Expected exactly one member to match the input <actual>"
Example (Formatting Standard Schema issues with defaultLeafHook)
import { SchemaIssue } from "effect"
const formatter = SchemaIssue.makeFormatterStandardSchemaV1({ leafHook: SchemaIssue.defaultLeafHook})See
LeafHookmakeFormatterStandardSchemaV1
Signature
declare const defaultLeafHook: LeafHookSince v4.0.0
makeFormatterDefault
Section titled “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 usingdefaultLeafHookanddefaultCheckHook. - Each entry is rendered as
"<message>"or"<message>\n at <path>". - Multiple entries are joined with newlines.
Example (Formatting an issue as a string)
import { SchemaIssue } from "effect"
const formatter = SchemaIssue.makeFormatterDefault()See
makeFormatterStandardSchemaV1— produces Standard Schema V1 format insteadFormatter
Signature
declare const makeFormatterDefault: () => Formatter<string>Since v4.0.0
makeFormatterStandardSchemaV1
Section titled “makeFormatterStandardSchemaV1”Creates a Formatter that produces a StandardSchemaV1.FailureResult.
When to use
Use when you need schema parse errors in Standard Schema V1 format, optionally customizing leaf or check issue rendering.
Details
- Returns a
Formatter<StandardSchemaV1.FailureResult>. - Each leaf issue is flattened into
{ message, path }entries. Pointerpaths are accumulated to produce full property paths.- Falls back to
defaultLeafHook/defaultCheckHookwhen no hooks are provided.
Example (Creating a Standard Schema V1 formatter)
import { SchemaIssue } from "effect"
const formatter = SchemaIssue.makeFormatterStandardSchemaV1()See
makeFormatterDefault— produces a plain string insteadLeafHookCheckHook
Signature
declare const makeFormatterStandardSchemaV1: (options?: { readonly leafHook?: LeafHook | undefined readonly checkHook?: CheckHook | undefined}) => Formatter<StandardSchemaV1.FailureResult>Since v4.0.0
getters
Section titled “getters”getActual
Section titled “getActual”Extracts the actual input value from any Issue variant.
When to use
Use when you need to retrieve an Issue’s offending input value for logging
or custom error rendering.
Details
- Returns
Option.none()forPointerandMissingKey(they carry no value). - Returns the existing
Optionfor variants that already storeactualasOption<unknown>(InvalidType,InvalidValue,Forbidden,Encoding,Composite). - Wraps
actualwithOption.somefor variants that store it as plainunknown(AnyOf,UnexpectedKey,OneOf,Filter).
Example (Extracting the actual value)
import { Option, SchemaIssue } from "effect"
const issue = new SchemaIssue.MissingKey(undefined)console.log(SchemaIssue.getActual(issue))// { _tag: "None" }See
IssueisIssue
Signature
declare const getActual: (issue: Issue) => Option.Option<unknown>Since v4.0.0
guards
Section titled “guards”isIssue
Section titled “isIssue”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
TypeIdbrand on the value.
Example (Type-guarding an unknown error)
import { SchemaIssue } from "effect"
const issue = new SchemaIssue.MissingKey(undefined)console.log(SchemaIssue.isIssue(issue))// trueconsole.log(SchemaIssue.isIssue("not an issue"))// falseSee
Issue
Signature
declare const isIssue: (u: unknown) => u is IssueSince v4.0.0
models
Section titled “models”AnyOf (class)
Section titled “AnyOf (class)”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
astis theUnionAST node.actualis the raw input value (plainunknown).issuescontains per-member failures. When empty, the formatter falls back to the union’sexpectedannotation.
See
OneOf— the opposite: too many members matchedComposite— groups multiple issues under a non-union schema
Signature
declare class AnyOf { constructor( /** * The schema that caused the issue. */ ast: SchemaAST.Union, /** * The input value that caused the issue. */ actual: unknown, /** * The issues that occurred. */ issues: ReadonlyArray<Issue> )}Since v4.0.0
_tag (property)
Section titled “_tag (property)”Signature
readonly _tag: "AnyOf"ast (property)
Section titled “ast (property)”The schema that caused the issue.
Signature
readonly ast: SchemaAST.Union<SchemaAST.AST>actual (property)
Section titled “actual (property)”The input value that caused the issue.
Signature
readonly actual: unknownissues (property)
Section titled “issues (property)”The issues that occurred.
Signature
readonly issues: ReadonlyArray<Issue>Composite (class)
Section titled “Composite (class)”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
issuesis a non-empty readonly array (at least one child).actualisOption.some(value)when the input was present, orOption.none()when absent.- Formatters flatten
Compositeby 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 { constructor( /** * The schema that caused the issue. */ ast: SchemaAST.AST, /** * The input value that caused the issue. */ actual: Option.Option<unknown>, /** * The issues that occurred. */ issues: readonly [Issue, ...Array<Issue>] )}Since v3.10.0
_tag (property)
Section titled “_tag (property)”Signature
readonly _tag: "Composite"ast (property)
Section titled “ast (property)”The schema that caused the issue.
Signature
readonly ast: SchemaAST.ASTactual (property)
Section titled “actual (property)”The input value that caused the issue.
Signature
readonly actual: Option.Option<unknown>issues (property)
Section titled “issues (property)”The issues that occurred.
Signature
readonly issues: readonly [Issue, ...Issue[]]Encoding (class)
Section titled “Encoding (class)”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
astis the AST node for the transformation that failed.actualisOption.some(value)when the input was present, orOption.none()when it was absent.issueis 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 { constructor( /** * The schema that caused the issue. */ ast: SchemaAST.AST, /** * The input value that caused the issue. */ actual: Option.Option<unknown>, /** * The issue that occurred. */ issue: Issue )}Since v4.0.0
_tag (property)
Section titled “_tag (property)”Signature
readonly _tag: "Encoding"ast (property)
Section titled “ast (property)”The schema that caused the issue.
Signature
readonly ast: SchemaAST.ASTactual (property)
Section titled “actual (property)”The input value that caused the issue.
Signature
readonly actual: Option.Option<unknown>issue (property)
Section titled “issue (property)”The issue that occurred.
Signature
readonly issue: IssueFilter (class)
Section titled “Filter (class)”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
actualis the raw input value that was tested (plainunknown, not wrapped inOption).filteris the AST filter node that produced this issue.issueis the inner issue describing the failure reason.
Example (Matching a Filter issue)
import { SchemaIssue } from "effect"
function describe(issue: SchemaIssue.Issue): string { if (issue._tag === "Filter") { return `Filter failed on: ${JSON.stringify(issue.actual)}` } return String(issue)}See
Leaf— terminal issue types that commonly appear as the innerissueCheckHook— formatter hook forFilterissues
Signature
declare class Filter { constructor( /** * The input value that caused the issue. */ actual: unknown, /** * The filter that failed. */ filter: SchemaAST.Filter<any>, /** * The issue that occurred. */ issue: Issue )}Since v4.0.0
_tag (property)
Section titled “_tag (property)”Signature
readonly _tag: "Filter"actual (property)
Section titled “actual (property)”The input value that caused the issue.
Signature
readonly actual: unknownfilter (property)
Section titled “filter (property)”The filter that failed.
Signature
readonly filter: SchemaAST.Filter<unknown>issue (property)
Section titled “issue (property)”The issue that occurred.
Signature
readonly issue: IssueForbidden (class)
Section titled “Forbidden (class)”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
actualisOption.some(value)when the input is known, orOption.none()when absent.annotationsoptionally carries amessagestring.- The default formatter renders this as
"Forbidden operation".
Example (Creating a Forbidden issue)
import { Option, SchemaIssue } from "effect"
const issue = new SchemaIssue.Forbidden(Option.none(), { message: "async operation not allowed in sync context" })console.log(String(issue))// "async operation not allowed in sync context"See
InvalidValue— for value-constraint failures (not operation failures)
Signature
declare class Forbidden { constructor( /** * The input value that caused the issue. */ actual: Option.Option<unknown>, /** * The metadata for the issue. */ annotations: Schema.Annotations.Issue | undefined )}Since v3.10.0
_tag (property)
Section titled “_tag (property)”Signature
readonly _tag: "Forbidden"actual (property)
Section titled “actual (property)”The input value that caused the issue.
Signature
readonly actual: Option.Option<unknown>annotations (property)
Section titled “annotations (property)”The metadata for the issue.
Signature
readonly annotations: Schema.Annotations.Issue | undefinedInvalidType (class)
Section titled “InvalidType (class)”Represents a schema issue produced when the runtime type of the input does not match the type
expected by the schema (e.g. got null when string was expected).
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
astis the schema node that expected a different type.actualisOption.some(value)when the input was present, orOption.none()when no value was provided.- The default formatter renders this as
"Expected <type>, got <actual>".
Example (Formatting output)
import { Schema } from "effect"
try { Schema.decodeUnknownSync(Schema.String)(42)} catch (e) { if (Schema.isSchemaError(e)) { console.log(String(e.issue)) // "Expected string, got 42" }}See
InvalidValue— the input has the right type but fails a value constraint
Signature
declare class InvalidType { constructor( /** * The schema that caused the issue. */ ast: SchemaAST.AST, /** * The input value that caused the issue. */ actual: Option.Option<unknown> )}Since v4.0.0
_tag (property)
Section titled “_tag (property)”Signature
readonly _tag: "InvalidType"ast (property)
Section titled “ast (property)”The schema that caused the issue.
Signature
readonly ast: SchemaAST.ASTactual (property)
Section titled “actual (property)”The input value that caused the issue.
Signature
readonly actual: Option.Option<unknown>InvalidValue (class)
Section titled “InvalidValue (class)”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
actualisOption.some(value)when the failing value is known, orOption.none()when absent.annotationsoptionally carries amessagestring for formatting.- The default formatter renders this as
"Invalid data <actual>"unless a custommessageannotation is provided.
Example (Returning InvalidValue from a custom filter)
import { Option, SchemaIssue } from "effect"
const issue = new SchemaIssue.InvalidValue(Option.some(""), { message: "must not be empty" })console.log(String(issue))// "must not be empty"See
InvalidType— the input has the wrong type entirelyFilter— composite wrapper when a schema filter produces this issue
Signature
declare class InvalidValue { constructor( /** * The value that caused the issue. */ actual: Option.Option<unknown>, /** * The metadata for the issue. */ annotations?: Schema.Annotations.Issue | undefined )}Since v4.0.0
_tag (property)
Section titled “_tag (property)”Signature
readonly _tag: "InvalidValue"actual (property)
Section titled “actual (property)”The value that caused the issue.
Signature
readonly actual: Option.Option<unknown>annotations (property)
Section titled “annotations (property)”The metadata for the issue.
Signature
readonly annotations: Schema.Annotations.Issue | undefinedIssue (type alias)
Section titled “Issue (type alias)”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.
See
Leaf— the terminal subsetisIssue— type guardgetActual— extract the actual value from any issue
Signature
type Issue = | Leaf // composite | Filter | Encoding | Pointer | Composite | AnyOfSince v4.0.0
Leaf (type alias)
Section titled “Leaf (type alias)”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 nodesLeafHook— formatter hook that operates onLeafvalues
Signature
type Leaf = InvalidType | InvalidValue | MissingKey | UnexpectedKey | Forbidden | OneOfSince v4.0.0
MissingKey (class)
Section titled “MissingKey (class)”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
- Has no
actualvalue —getActualreturnsOption.none(). annotationsmay contain a custommessageMissingKeyfor formatting.
See
Pointer— wraps this issue with the missing key’s pathUnexpectedKey— the opposite case (extra key present)
Signature
declare class MissingKey { constructor( /** * The metadata for the issue. */ annotations: Schema.Annotations.Key<unknown> | undefined )}Since v4.0.0
_tag (property)
Section titled “_tag (property)”Signature
readonly _tag: "MissingKey"annotations (property)
Section titled “annotations (property)”The metadata for the issue.
Signature
readonly annotations: Schema.Annotations.Key<unknown> | undefinedOneOf (class)
Section titled “OneOf (class)”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
astis theUnionAST node.actualis the raw input value (plainunknown).successeslists the AST nodes of each member that accepted the input.- The default formatter renders this as
"Expected exactly one member to match the input <actual>".
See
AnyOf— the opposite: no members matched
Signature
declare class OneOf { constructor( /** * The schema that caused the issue. */ ast: SchemaAST.Union, /** * The input value that caused the issue. */ actual: unknown, /** * The schemas that were successful. */ successes: ReadonlyArray<SchemaAST.AST> )}Since v4.0.0
_tag (property)
Section titled “_tag (property)”Signature
readonly _tag: "OneOf"ast (property)
Section titled “ast (property)”The schema that caused the issue.
Signature
readonly ast: SchemaAST.Union<SchemaAST.AST>actual (property)
Section titled “actual (property)”The input value that caused the issue.
Signature
readonly actual: unknownsuccesses (property)
Section titled “successes (property)”The schemas that were successful.
Signature
readonly successes: ReadonlyArray<SchemaAST.AST>Pointer (class)
Section titled “Pointer (class)”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
pathis an array of property keys (strings, numbers, or symbols).- Has no
actualvalue —getActualreturnsOption.none(). - Formatters concatenate nested
Pointerpaths into a single path like["a"]["b"][0].
See
getActual— returnsOption.none()forPointerComposite— groups multiple issues under one schema node
Signature
declare class Pointer { constructor( /** * The path to the location in the input that caused the issue. */ path: ReadonlyArray<PropertyKey>, /** * The issue that occurred. */ issue: Issue )}Since v3.10.0
_tag (property)
Section titled “_tag (property)”Signature
readonly _tag: "Pointer"path (property)
Section titled “path (property)”The path to the location in the input that caused the issue.
Signature
readonly path: ReadonlyArray<PropertyKey>issue (property)
Section titled “issue (property)”The issue that occurred.
Signature
readonly issue: IssueUnexpectedKey (class)
Section titled “UnexpectedKey (class)”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
actualis the raw value at the unexpected key (plainunknown).astis the schema that was being validated against.annotationsonastmay contain a custommessageUnexpectedKey.
See
MissingKey— the opposite case (required key absent)Pointer— wraps this issue with the unexpected key’s path
Signature
declare class UnexpectedKey { constructor( /** * The schema that caused the issue. */ ast: SchemaAST.AST, /** * The input value that caused the issue. */ actual: unknown )}Since v4.0.0
_tag (property)
Section titled “_tag (property)”Signature
readonly _tag: "UnexpectedKey"ast (property)
Section titled “ast (property)”The schema that caused the issue.
Signature
readonly ast: SchemaAST.ASTactual (property)
Section titled “actual (property)”The input value that caused the issue.
Signature
readonly actual: unknown