Skip to content

Error Formatters

When working with Effect Schema, errors encountered during decoding or encoding operations can be formatted using two built-in methods: TreeFormatter and ArrayFormatter. These formatters help structure and present errors in a readable and actionable manner.

The TreeFormatter is the default method for formatting errors. It organizes errors in a tree structure, providing a clear hierarchy of issues.

Example (Decoding with Missing Properties)

import {
import Either

@since2.0.0

@since2.0.0

Either
,
import Schema
Schema
,
import ParseResult
ParseResult
} from "effect"
const
const Person: Schema.Struct<{
name: typeof Schema.String;
age: typeof Schema.Number;
}>
Person
=
import Schema
Schema
.
function Struct<{
name: typeof Schema.String;
age: typeof Schema.Number;
}>(fields: {
name: typeof Schema.String;
age: typeof Schema.Number;
}): Schema.Struct<{
name: typeof Schema.String;
age: typeof Schema.Number;
}> (+1 overload)

@since3.10.0

Struct
({
name: typeof Schema.String
name
:
import Schema
Schema
.
class String
export String

@since3.10.0

String
,
age: typeof Schema.Number
age
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
})
const
const decode: (u: unknown, overrideOptions?: ParseOptions) => Either.Either<{
readonly name: string;
readonly age: number;
}, ParseResult.ParseError>
decode
=
import Schema
Schema
.
const decodeUnknownEither: <{
readonly name: string;
readonly age: number;
}, {
readonly name: string;
readonly age: number;
}>(schema: Schema.Schema<{
readonly name: string;
readonly age: number;
}, {
readonly name: string;
readonly age: number;
}, never>, options?: ParseOptions) => (u: unknown, overrideOptions?: ParseOptions) => Either.Either<...>

@since3.10.0

decodeUnknownEither
(
const Person: Schema.Struct<{
name: typeof Schema.String;
age: typeof Schema.Number;
}>
Person
)
const
const result: Either.Either<{
readonly name: string;
readonly age: number;
}, ParseResult.ParseError>
result
=
const decode: (u: unknown, overrideOptions?: ParseOptions) => Either.Either<{
readonly name: string;
readonly age: number;
}, ParseResult.ParseError>
decode
({})
if (
import Either

@since2.0.0

@since2.0.0

Either
.
const isLeft: <{
readonly name: string;
readonly age: number;
}, ParseResult.ParseError>(self: Either.Either<{
readonly name: string;
readonly age: number;
}, ParseResult.ParseError>) => self is Either.Left<...>

Determine if a Either is a Left.

@paramself - The Either to check.

@example

import { Either } from "effect"
assert.deepStrictEqual(Either.isLeft(Either.right(1)), false)
assert.deepStrictEqual(Either.isLeft(Either.left("a")), true)

@since2.0.0

isLeft
(
const result: Either.Either<{
readonly name: string;
readonly age: number;
}, ParseResult.ParseError>
result
)) {
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.error(message?: any, ...optionalParams: any[]): void

Prints to stderr with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const code = 5;
console.error('error #%d', code);
// Prints: error #5, to stderr
console.error('error', code);
// Prints: error 5, to stderr

If formatting elements (e.g. %d) are not found in the first string then util.inspect() is called on each argument and the resulting string values are concatenated. See util.format() for more information.

@sincev0.1.100

error
("Decoding failed:")
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.error(message?: any, ...optionalParams: any[]): void

Prints to stderr with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const code = 5;
console.error('error #%d', code);
// Prints: error #5, to stderr
console.error('error', code);
// Prints: error 5, to stderr

If formatting elements (e.g. %d) are not found in the first string then util.inspect() is called on each argument and the resulting string values are concatenated. See util.format() for more information.

@sincev0.1.100

error
(
import ParseResult
ParseResult
.
const TreeFormatter: ParseResult.ParseResultFormatter<string>

@since3.10.0

TreeFormatter
.
ParseResultFormatter<string>.formatErrorSync: (error: ParseResult.ParseError) => string
formatErrorSync
(
const result: Either.Left<ParseResult.ParseError, {
readonly name: string;
readonly age: number;
}>
result
.
Left<ParseError, { readonly name: string; readonly age: number; }>.left: ParseResult.ParseError
left
))
}
/*
Decoding failed:
{ readonly name: string; readonly age: number }
└─ ["name"]
└─ is missing
*/

In this example:

  • { readonly name: string; readonly age: number } describes the schema’s expected structure.
  • ["name"] identifies the specific field causing the error.
  • is missing explains the issue for the "name" field.

You can make the error output more concise and meaningful by annotating the schema with annotations like identifier, title, or description. These annotations replace the default TypeScript-like representation in the error messages.

Example (Using title Annotation for Clarity)

Adding a title annotation replaces the schema structure in the error message with the more human-readable “Person” making it easier to understand.

import {
import Either

@since2.0.0

@since2.0.0

Either
,
import Schema
Schema
,
import ParseResult
ParseResult
} from "effect"
const
const Person: Schema.Struct<{
name: typeof Schema.String;
age: typeof Schema.Number;
}>
Person
=
import Schema
Schema
.
function Struct<{
name: typeof Schema.String;
age: typeof Schema.Number;
}>(fields: {
name: typeof Schema.String;
age: typeof Schema.Number;
}): Schema.Struct<{
name: typeof Schema.String;
age: typeof Schema.Number;
}> (+1 overload)

@since3.10.0

Struct
({
name: typeof Schema.String
name
:
import Schema
Schema
.
class String
export String

@since3.10.0

String
,
age: typeof Schema.Number
age
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
}).
Struct<{ name: typeof String$; age: typeof Number$; }>.annotations(annotations: Schema.Annotations.Schema<{
readonly name: string;
readonly age: number;
}, readonly []>): Schema.Struct<{
name: typeof Schema.String;
age: typeof Schema.Number;
}>

Merges a set of new annotations with existing ones, potentially overwriting any duplicates.

annotations
({
Annotations.Doc<{ readonly name: string; readonly age: number; }>.title?: string
title
: "Person" }) // Add a title annotation
const
const result: Either.Either<{
readonly name: string;
readonly age: number;
}, ParseResult.ParseError>
result
=
import Schema
Schema
.
const decodeUnknownEither: <{
readonly name: string;
readonly age: number;
}, {
readonly name: string;
readonly age: number;
}>(schema: Schema.Schema<{
readonly name: string;
readonly age: number;
}, {
readonly name: string;
readonly age: number;
}, never>, options?: ParseOptions) => (u: unknown, overrideOptions?: ParseOptions) => Either.Either<...>

@since3.10.0

decodeUnknownEither
(
const Person: Schema.Struct<{
name: typeof Schema.String;
age: typeof Schema.Number;
}>
Person
)({})
if (
import Either

@since2.0.0

@since2.0.0

Either
.
const isLeft: <{
readonly name: string;
readonly age: number;
}, ParseResult.ParseError>(self: Either.Either<{
readonly name: string;
readonly age: number;
}, ParseResult.ParseError>) => self is Either.Left<...>

Determine if a Either is a Left.

@paramself - The Either to check.

@example

import { Either } from "effect"
assert.deepStrictEqual(Either.isLeft(Either.right(1)), false)
assert.deepStrictEqual(Either.isLeft(Either.left("a")), true)

@since2.0.0

isLeft
(
const result: Either.Either<{
readonly name: string;
readonly age: number;
}, ParseResult.ParseError>
result
)) {
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.error(message?: any, ...optionalParams: any[]): void

Prints to stderr with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const code = 5;
console.error('error #%d', code);
// Prints: error #5, to stderr
console.error('error', code);
// Prints: error 5, to stderr

If formatting elements (e.g. %d) are not found in the first string then util.inspect() is called on each argument and the resulting string values are concatenated. See util.format() for more information.

@sincev0.1.100

error
(
import ParseResult
ParseResult
.
const TreeFormatter: ParseResult.ParseResultFormatter<string>

@since3.10.0

TreeFormatter
.
ParseResultFormatter<string>.formatErrorSync: (error: ParseResult.ParseError) => string
formatErrorSync
(
const result: Either.Left<ParseResult.ParseError, {
readonly name: string;
readonly age: number;
}>
result
.
Left<ParseError, { readonly name: string; readonly age: number; }>.left: ParseResult.ParseError
left
))
}
/*
Person
└─ ["name"]
└─ is missing
*/

By default, decoding functions like Schema.decodeUnknownEither report only the first error. To list all errors, use the { errors: "all" } option.

Example (Listing All Errors)

import {
import Either

@since2.0.0

@since2.0.0

Either
,
import Schema
Schema
,
import ParseResult
ParseResult
} from "effect"
const
const Person: Schema.Struct<{
name: typeof Schema.String;
age: typeof Schema.Number;
}>
Person
=
import Schema
Schema
.
function Struct<{
name: typeof Schema.String;
age: typeof Schema.Number;
}>(fields: {
name: typeof Schema.String;
age: typeof Schema.Number;
}): Schema.Struct<{
name: typeof Schema.String;
age: typeof Schema.Number;
}> (+1 overload)

@since3.10.0

Struct
({
name: typeof Schema.String
name
:
import Schema
Schema
.
class String
export String

@since3.10.0

String
,
age: typeof Schema.Number
age
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
})
const
const decode: (u: unknown, overrideOptions?: ParseOptions) => Either.Either<{
readonly name: string;
readonly age: number;
}, ParseResult.ParseError>
decode
=
import Schema
Schema
.
const decodeUnknownEither: <{
readonly name: string;
readonly age: number;
}, {
readonly name: string;
readonly age: number;
}>(schema: Schema.Schema<{
readonly name: string;
readonly age: number;
}, {
readonly name: string;
readonly age: number;
}, never>, options?: ParseOptions) => (u: unknown, overrideOptions?: ParseOptions) => Either.Either<...>

@since3.10.0

decodeUnknownEither
(
const Person: Schema.Struct<{
name: typeof Schema.String;
age: typeof Schema.Number;
}>
Person
, {
ParseOptions.errors?: "first" | "all" | undefined

The errors option allows you to receive all parsing errors when attempting to parse a value using a schema. By default only the first error is returned, but by setting the errors option to "all", you can receive all errors that occurred during the parsing process. This can be useful for debugging or for providing more comprehensive error messages to the user.

default: "first"

@since3.10.0

errors
: "all" })
const
const result: Either.Either<{
readonly name: string;
readonly age: number;
}, ParseResult.ParseError>
result
=
const decode: (u: unknown, overrideOptions?: ParseOptions) => Either.Either<{
readonly name: string;
readonly age: number;
}, ParseResult.ParseError>
decode
({})
if (
import Either

@since2.0.0

@since2.0.0

Either
.
const isLeft: <{
readonly name: string;
readonly age: number;
}, ParseResult.ParseError>(self: Either.Either<{
readonly name: string;
readonly age: number;
}, ParseResult.ParseError>) => self is Either.Left<...>

Determine if a Either is a Left.

@paramself - The Either to check.

@example

import { Either } from "effect"
assert.deepStrictEqual(Either.isLeft(Either.right(1)), false)
assert.deepStrictEqual(Either.isLeft(Either.left("a")), true)

@since2.0.0

isLeft
(
const result: Either.Either<{
readonly name: string;
readonly age: number;
}, ParseResult.ParseError>
result
)) {
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.error(message?: any, ...optionalParams: any[]): void

Prints to stderr with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const code = 5;
console.error('error #%d', code);
// Prints: error #5, to stderr
console.error('error', code);
// Prints: error 5, to stderr

If formatting elements (e.g. %d) are not found in the first string then util.inspect() is called on each argument and the resulting string values are concatenated. See util.format() for more information.

@sincev0.1.100

error
("Decoding failed:")
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.error(message?: any, ...optionalParams: any[]): void

Prints to stderr with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const code = 5;
console.error('error #%d', code);
// Prints: error #5, to stderr
console.error('error', code);
// Prints: error 5, to stderr

If formatting elements (e.g. %d) are not found in the first string then util.inspect() is called on each argument and the resulting string values are concatenated. See util.format() for more information.

@sincev0.1.100

error
(
import ParseResult
ParseResult
.
const TreeFormatter: ParseResult.ParseResultFormatter<string>

@since3.10.0

TreeFormatter
.
ParseResultFormatter<string>.formatErrorSync: (error: ParseResult.ParseError) => string
formatErrorSync
(
const result: Either.Left<ParseResult.ParseError, {
readonly name: string;
readonly age: number;
}>
result
.
Left<ParseError, { readonly name: string; readonly age: number; }>.left: ParseResult.ParseError
left
))
}
/*
Decoding failed:
{ readonly name: string; readonly age: number }
├─ ["name"]
│ └─ is missing
└─ ["age"]
└─ is missing
*/

The parseIssueTitle annotation allows you to add dynamic context to error messages by generating titles based on the value being validated. For instance, it can include an ID from the validated object, making it easier to identify specific issues in complex or nested data structures.

Annotation Type

export type ParseIssueTitleAnnotation = (
issue: ParseIssue
) => string | undefined

Return Value:

  • If the function returns a string, the TreeFormatter uses it as the title unless a message annotation is present (which takes precedence).
  • If the function returns undefined, the TreeFormatter determines the title based on the following priority:
    1. identifier annotation
    2. title annotation
    3. description annotation
    4. Default TypeScript-like schema representation

Example (Dynamic Titles Using parseIssueTitle)

import type {
import ParseResult
ParseResult
} from "effect"
import {
import Schema
Schema
} from "effect"
// Function to generate titles for OrderItem issues
const
const getOrderItemId: ({ actual }: ParseResult.ParseIssue) => string | undefined
getOrderItemId
= ({
actual: unknown
actual
}:
import ParseResult
ParseResult
.
type ParseIssue = ParseResult.Type | ParseResult.Missing | ParseResult.Unexpected | ParseResult.Forbidden | ParseResult.Pointer | ParseResult.Refinement | ParseResult.Transformation | ParseResult.Composite

ParseIssue is a type that represents the different types of errors that can occur when decoding/encoding a value.

@since3.10.0

ParseIssue
) => {
if (
import Schema
Schema
.
is<{
readonly id: string;
}, {
readonly id: string;
}, never>(schema: Schema.Schema<{
readonly id: string;
}, {
readonly id: string;
}, never>, options?: ParseOptions): (u: unknown, overrideOptions?: ParseOptions | number) => u is {
readonly id: string;
}
export is

By default the option exact is set to true.

@since3.10.0

is
(
import Schema
Schema
.
function Struct<{
id: typeof Schema.String;
}>(fields: {
id: typeof Schema.String;
}): Schema.Struct<{
id: typeof Schema.String;
}> (+1 overload)

@since3.10.0

Struct
({
id: typeof Schema.String
id
:
import Schema
Schema
.
class String
export String

@since3.10.0

String
}))(
actual: unknown
actual
)) {
return `OrderItem with id: ${
actual: {
readonly id: string;
}
actual
.
id: string
id
}`
}
}
const
const OrderItem: Schema.Struct<{
id: typeof Schema.String;
name: typeof Schema.String;
price: typeof Schema.Number;
}>
OrderItem
=
import Schema
Schema
.
function Struct<{
id: typeof Schema.String;
name: typeof Schema.String;
price: typeof Schema.Number;
}>(fields: {
id: typeof Schema.String;
name: typeof Schema.String;
price: typeof Schema.Number;
}): Schema.Struct<...> (+1 overload)

@since3.10.0

Struct
({
id: typeof Schema.String
id
:
import Schema
Schema
.
class String
export String

@since3.10.0

String
,
name: typeof Schema.String
name
:
import Schema
Schema
.
class String
export String

@since3.10.0

String
,
price: typeof Schema.Number
price
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
}).
Struct<{ id: typeof String$; name: typeof String$; price: typeof Number$; }>.annotations(annotations: Schema.Annotations.Schema<{
readonly id: string;
readonly name: string;
readonly price: number;
}, readonly []>): Schema.Struct<{
id: typeof Schema.String;
name: typeof Schema.String;
price: typeof Schema.Number;
}>

Merges a set of new annotations with existing ones, potentially overwriting any duplicates.

annotations
({
Annotations.Schema<A, TypeParameters extends ReadonlyArray<any> = readonly []>.identifier?: string
identifier
: "OrderItem",
Annotations.Schema<A, TypeParameters extends ReadonlyArray<any> = readonly []>.parseIssueTitle?: ParseIssueTitleAnnotation
parseIssueTitle
:
const getOrderItemId: ({ actual }: ParseResult.ParseIssue) => string | undefined
getOrderItemId
})
// Function to generate titles for Order issues
const
const getOrderId: ({ actual }: ParseResult.ParseIssue) => string | undefined
getOrderId
= ({
actual: unknown
actual
}:
import ParseResult
ParseResult
.
type ParseIssue = ParseResult.Type | ParseResult.Missing | ParseResult.Unexpected | ParseResult.Forbidden | ParseResult.Pointer | ParseResult.Refinement | ParseResult.Transformation | ParseResult.Composite

ParseIssue is a type that represents the different types of errors that can occur when decoding/encoding a value.

@since3.10.0

ParseIssue
) => {
if (
import Schema
Schema
.
is<{
readonly id: number;
}, {
readonly id: number;
}, never>(schema: Schema.Schema<{
readonly id: number;
}, {
readonly id: number;
}, never>, options?: ParseOptions): (u: unknown, overrideOptions?: ParseOptions | number) => u is {
readonly id: number;
}
export is

By default the option exact is set to true.

@since3.10.0

is
(
import Schema
Schema
.
function Struct<{
id: typeof Schema.Number;
}>(fields: {
id: typeof Schema.Number;
}): Schema.Struct<{
id: typeof Schema.Number;
}> (+1 overload)

@since3.10.0

Struct
({
id: typeof Schema.Number
id
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
}))(
actual: unknown
actual
)) {
return `Order with id: ${
actual: {
readonly id: number;
}
actual
.
id: number
id
}`
}
}
const
const Order: Schema.Struct<{
id: typeof Schema.Number;
name: typeof Schema.String;
items: Schema.Array$<Schema.Struct<{
id: typeof Schema.String;
name: typeof Schema.String;
price: typeof Schema.Number;
}>>;
}>
Order
=
import Schema
Schema
.
function Struct<{
id: typeof Schema.Number;
name: typeof Schema.String;
items: Schema.Array$<Schema.Struct<{
id: typeof Schema.String;
name: typeof Schema.String;
price: typeof Schema.Number;
}>>;
}>(fields: {
id: typeof Schema.Number;
name: typeof Schema.String;
items: Schema.Array$<Schema.Struct<{
id: typeof Schema.String;
name: typeof Schema.String;
price: typeof Schema.Number;
}>>;
}): Schema.Struct<...> (+1 overload)

@since3.10.0

Struct
({
id: typeof Schema.Number
id
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
,
name: typeof Schema.String
name
:
import Schema
Schema
.
class String
export String

@since3.10.0

String
,
items: Schema.Array$<Schema.Struct<{
id: typeof Schema.String;
name: typeof Schema.String;
price: typeof Schema.Number;
}>>
items
:
import Schema
Schema
.
Array<Schema.Struct<{
id: typeof Schema.String;
name: typeof Schema.String;
price: typeof Schema.Number;
}>>(value: Schema.Struct<{
id: typeof Schema.String;
name: typeof Schema.String;
price: typeof Schema.Number;
}>): Schema.Array$<...>
export Array

@since3.10.0

Array
(
const OrderItem: Schema.Struct<{
id: typeof Schema.String;
name: typeof Schema.String;
price: typeof Schema.Number;
}>
OrderItem
)
}).
Struct<{ id: typeof Number$; name: typeof String$; items: Array$<Struct<{ id: typeof String$; name: typeof String$; price: typeof Number$; }>>; }>.annotations(annotations: Schema.Annotations.Schema<{
readonly id: number;
readonly name: string;
readonly items: readonly {
readonly id: string;
readonly name: string;
readonly price: number;
}[];
}, readonly []>): Schema.Struct<...>

Merges a set of new annotations with existing ones, potentially overwriting any duplicates.

annotations
({
Annotations.Schema<A, TypeParameters extends ReadonlyArray<any> = readonly []>.identifier?: string
identifier
: "Order",
Annotations.Schema<A, TypeParameters extends ReadonlyArray<any> = readonly []>.parseIssueTitle?: ParseIssueTitleAnnotation
parseIssueTitle
:
const getOrderId: ({ actual }: ParseResult.ParseIssue) => string | undefined
getOrderId
})
const
const decode: (u: unknown, overrideOptions?: ParseOptions) => {
readonly id: number;
readonly name: string;
readonly items: readonly {
readonly id: string;
readonly name: string;
readonly price: number;
}[];
}
decode
=
import Schema
Schema
.
decodeUnknownSync<{
readonly id: number;
readonly name: string;
readonly items: readonly {
readonly id: string;
readonly name: string;
readonly price: number;
}[];
}, {
readonly id: number;
readonly name: string;
readonly items: readonly {
...;
}[];
}>(schema: Schema.Schema<...>, options?: ParseOptions): (u: unknown, overrideOptions?: ParseOptions) => {
readonly id: number;
readonly name: string;
readonly items: readonly {
readonly id: string;
readonly name: string;
readonly price: number;
}[];
}
export decodeUnknownSync

@throwsParseError

@since3.10.0

decodeUnknownSync
(
const Order: Schema.Struct<{
id: typeof Schema.Number;
name: typeof Schema.String;
items: Schema.Array$<Schema.Struct<{
id: typeof Schema.String;
name: typeof Schema.String;
price: typeof Schema.Number;
}>>;
}>
Order
, {
ParseOptions.errors?: "first" | "all" | undefined

The errors option allows you to receive all parsing errors when attempting to parse a value using a schema. By default only the first error is returned, but by setting the errors option to "all", you can receive all errors that occurred during the parsing process. This can be useful for debugging or for providing more comprehensive error messages to the user.

default: "first"

@since3.10.0

errors
: "all" })
// Case 1: No id available, uses the `identifier` annotation
const decode: (u: unknown, overrideOptions?: ParseOptions) => {
readonly id: number;
readonly name: string;
readonly items: readonly {
readonly id: string;
readonly name: string;
readonly price: number;
}[];
}
decode
({})
/*
throws
ParseError: Order
├─ ["id"]
│ └─ is missing
├─ ["name"]
│ └─ is missing
└─ ["items"]
└─ is missing
*/
// Case 2: ID present, uses the dynamic `parseIssueTitle` annotation
const decode: (u: unknown, overrideOptions?: ParseOptions) => {
readonly id: number;
readonly name: string;
readonly items: readonly {
readonly id: string;
readonly name: string;
readonly price: number;
}[];
}
decode
({
id: number
id
: 1 })
/*
throws
ParseError: Order with id: 1
├─ ["name"]
│ └─ is missing
└─ ["items"]
└─ is missing
*/
// Case 3: Nested issues with IDs for both Order and OrderItem
const decode: (u: unknown, overrideOptions?: ParseOptions) => {
readonly id: number;
readonly name: string;
readonly items: readonly {
readonly id: string;
readonly name: string;
readonly price: number;
}[];
}
decode
({
id: number
id
: 1,
items: {
id: string;
price: string;
}[]
items
: [{
id: string
id
: "22b",
price: string
price
: "100" }] })
/*
throws
ParseError: Order with id: 1
├─ ["name"]
│ └─ is missing
└─ ["items"]
└─ ReadonlyArray<OrderItem>
└─ [0]
└─ OrderItem with id: 22b
├─ ["name"]
│ └─ is missing
└─ ["price"]
└─ Expected a number, actual "100"
*/

The ArrayFormatter provides a structured, array-based approach to formatting errors. It represents each error as an object, making it easier to analyze and address multiple issues during data decoding or encoding. Each error object includes properties like _tag, path, and message for clarity.

Example (Single Error in Array Format)

import {
import Either

@since2.0.0

@since2.0.0

Either
,
import Schema
Schema
,
import ParseResult
ParseResult
} from "effect"
const
const Person: Schema.Struct<{
name: typeof Schema.String;
age: typeof Schema.Number;
}>
Person
=
import Schema
Schema
.
function Struct<{
name: typeof Schema.String;
age: typeof Schema.Number;
}>(fields: {
name: typeof Schema.String;
age: typeof Schema.Number;
}): Schema.Struct<{
name: typeof Schema.String;
age: typeof Schema.Number;
}> (+1 overload)

@since3.10.0

Struct
({
name: typeof Schema.String
name
:
import Schema
Schema
.
class String
export String

@since3.10.0

String
,
age: typeof Schema.Number
age
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
})
const
const decode: (u: unknown, overrideOptions?: ParseOptions) => Either.Either<{
readonly name: string;
readonly age: number;
}, ParseResult.ParseError>
decode
=
import Schema
Schema
.
const decodeUnknownEither: <{
readonly name: string;
readonly age: number;
}, {
readonly name: string;
readonly age: number;
}>(schema: Schema.Schema<{
readonly name: string;
readonly age: number;
}, {
readonly name: string;
readonly age: number;
}, never>, options?: ParseOptions) => (u: unknown, overrideOptions?: ParseOptions) => Either.Either<...>

@since3.10.0

decodeUnknownEither
(
const Person: Schema.Struct<{
name: typeof Schema.String;
age: typeof Schema.Number;
}>
Person
)
const
const result: Either.Either<{
readonly name: string;
readonly age: number;
}, ParseResult.ParseError>
result
=
const decode: (u: unknown, overrideOptions?: ParseOptions) => Either.Either<{
readonly name: string;
readonly age: number;
}, ParseResult.ParseError>
decode
({})
if (
import Either

@since2.0.0

@since2.0.0

Either
.
const isLeft: <{
readonly name: string;
readonly age: number;
}, ParseResult.ParseError>(self: Either.Either<{
readonly name: string;
readonly age: number;
}, ParseResult.ParseError>) => self is Either.Left<...>

Determine if a Either is a Left.

@paramself - The Either to check.

@example

import { Either } from "effect"
assert.deepStrictEqual(Either.isLeft(Either.right(1)), false)
assert.deepStrictEqual(Either.isLeft(Either.left("a")), true)

@since2.0.0

isLeft
(
const result: Either.Either<{
readonly name: string;
readonly age: number;
}, ParseResult.ParseError>
result
)) {
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.error(message?: any, ...optionalParams: any[]): void

Prints to stderr with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const code = 5;
console.error('error #%d', code);
// Prints: error #5, to stderr
console.error('error', code);
// Prints: error 5, to stderr

If formatting elements (e.g. %d) are not found in the first string then util.inspect() is called on each argument and the resulting string values are concatenated. See util.format() for more information.

@sincev0.1.100

error
("Decoding failed:")
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.error(message?: any, ...optionalParams: any[]): void

Prints to stderr with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const code = 5;
console.error('error #%d', code);
// Prints: error #5, to stderr
console.error('error', code);
// Prints: error 5, to stderr

If formatting elements (e.g. %d) are not found in the first string then util.inspect() is called on each argument and the resulting string values are concatenated. See util.format() for more information.

@sincev0.1.100

error
(
import ParseResult
ParseResult
.
const ArrayFormatter: ParseResult.ParseResultFormatter<ParseResult.ArrayFormatterIssue[]>

@since3.10.0

ArrayFormatter
.
ParseResultFormatter<ArrayFormatterIssue[]>.formatErrorSync: (error: ParseResult.ParseError) => ParseResult.ArrayFormatterIssue[]
formatErrorSync
(
const result: Either.Left<ParseResult.ParseError, {
readonly name: string;
readonly age: number;
}>
result
.
Left<ParseError, { readonly name: string; readonly age: number; }>.left: ParseResult.ParseError
left
))
}
/*
Decoding failed:
[ { _tag: 'Missing', path: [ 'name' ], message: 'is missing' } ]
*/

In this example:

  • _tag: Indicates the type of error (Missing).
  • path: Specifies the location of the error in the data (['name']).
  • message: Describes the issue ('is missing').

By default, decoding functions like Schema.decodeUnknownEither report only the first error. To list all errors, use the { errors: "all" } option.

Example (Listing All Errors)

import {
import Either

@since2.0.0

@since2.0.0

Either
,
import Schema
Schema
,
import ParseResult
ParseResult
} from "effect"
const
const Person: Schema.Struct<{
name: typeof Schema.String;
age: typeof Schema.Number;
}>
Person
=
import Schema
Schema
.
function Struct<{
name: typeof Schema.String;
age: typeof Schema.Number;
}>(fields: {
name: typeof Schema.String;
age: typeof Schema.Number;
}): Schema.Struct<{
name: typeof Schema.String;
age: typeof Schema.Number;
}> (+1 overload)

@since3.10.0

Struct
({
name: typeof Schema.String
name
:
import Schema
Schema
.
class String
export String

@since3.10.0

String
,
age: typeof Schema.Number
age
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
})
const
const decode: (u: unknown, overrideOptions?: ParseOptions) => Either.Either<{
readonly name: string;
readonly age: number;
}, ParseResult.ParseError>
decode
=
import Schema
Schema
.
const decodeUnknownEither: <{
readonly name: string;
readonly age: number;
}, {
readonly name: string;
readonly age: number;
}>(schema: Schema.Schema<{
readonly name: string;
readonly age: number;
}, {
readonly name: string;
readonly age: number;
}, never>, options?: ParseOptions) => (u: unknown, overrideOptions?: ParseOptions) => Either.Either<...>

@since3.10.0

decodeUnknownEither
(
const Person: Schema.Struct<{
name: typeof Schema.String;
age: typeof Schema.Number;
}>
Person
, {
ParseOptions.errors?: "first" | "all" | undefined

The errors option allows you to receive all parsing errors when attempting to parse a value using a schema. By default only the first error is returned, but by setting the errors option to "all", you can receive all errors that occurred during the parsing process. This can be useful for debugging or for providing more comprehensive error messages to the user.

default: "first"

@since3.10.0

errors
: "all" })
const
const result: Either.Either<{
readonly name: string;
readonly age: number;
}, ParseResult.ParseError>
result
=
const decode: (u: unknown, overrideOptions?: ParseOptions) => Either.Either<{
readonly name: string;
readonly age: number;
}, ParseResult.ParseError>
decode
({})
if (
import Either

@since2.0.0

@since2.0.0

Either
.
const isLeft: <{
readonly name: string;
readonly age: number;
}, ParseResult.ParseError>(self: Either.Either<{
readonly name: string;
readonly age: number;
}, ParseResult.ParseError>) => self is Either.Left<...>

Determine if a Either is a Left.

@paramself - The Either to check.

@example

import { Either } from "effect"
assert.deepStrictEqual(Either.isLeft(Either.right(1)), false)
assert.deepStrictEqual(Either.isLeft(Either.left("a")), true)

@since2.0.0

isLeft
(
const result: Either.Either<{
readonly name: string;
readonly age: number;
}, ParseResult.ParseError>
result
)) {
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.error(message?: any, ...optionalParams: any[]): void

Prints to stderr with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const code = 5;
console.error('error #%d', code);
// Prints: error #5, to stderr
console.error('error', code);
// Prints: error 5, to stderr

If formatting elements (e.g. %d) are not found in the first string then util.inspect() is called on each argument and the resulting string values are concatenated. See util.format() for more information.

@sincev0.1.100

error
("Decoding failed:")
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.error(message?: any, ...optionalParams: any[]): void

Prints to stderr with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const code = 5;
console.error('error #%d', code);
// Prints: error #5, to stderr
console.error('error', code);
// Prints: error 5, to stderr

If formatting elements (e.g. %d) are not found in the first string then util.inspect() is called on each argument and the resulting string values are concatenated. See util.format() for more information.

@sincev0.1.100

error
(
import ParseResult
ParseResult
.
const ArrayFormatter: ParseResult.ParseResultFormatter<ParseResult.ArrayFormatterIssue[]>

@since3.10.0

ArrayFormatter
.
ParseResultFormatter<ArrayFormatterIssue[]>.formatErrorSync: (error: ParseResult.ParseError) => ParseResult.ArrayFormatterIssue[]
formatErrorSync
(
const result: Either.Left<ParseResult.ParseError, {
readonly name: string;
readonly age: number;
}>
result
.
Left<ParseError, { readonly name: string; readonly age: number; }>.left: ParseResult.ParseError
left
))
}
/*
Decoding failed:
[
{ _tag: 'Missing', path: [ 'name' ], message: 'is missing' },
{ _tag: 'Missing', path: [ 'age' ], message: 'is missing' }
]
*/

If you are working with React and need form validation, @hookform/resolvers offers an adapter for effect/Schema, which can be integrated with React Hook Form for enhanced form validation processes. This integration allows you to leverage the powerful features of effect/Schema within your React applications.

For more detailed instructions and examples on how to integrate effect/Schema with React Hook Form using @hookform/resolvers, you can visit the official npm package page: React Hook Form Resolvers