SchemaErrorError thrown (or returned as the error channel value) when schema decoding or encoding fails.
Details
The issue field contains a structured Issue tree describing
every validation failure, including the path to the problematic value,
expected types, and actual values received. message renders the issue tree
as a human-readable string.
Use isSchemaError to narrow an unknown value to SchemaError.
Example (Catching a SchemaError)
import { Schema } from "effect"
try {
Schema.decodeUnknownSync(Schema.Number)("not a number")
} catch (err) {
if (Schema.isSchemaError(err)) {
console.log(err.message)
// Expected number, actual "not a number"
}
}export class class SchemaErrorclass SchemaError {
message: string;
toString: () => string;
name: string;
stack: string;
cause: unknown;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toJSON: () => unknown;
_tag: Tag;
issue: Issue;
}
Error thrown (or returned as the error channel value) when schema decoding
or encoding fails.
Details
The issue field contains a structured
Issue
tree describing
every validation failure, including the path to the problematic value,
expected types, and actual values received. message renders the issue tree
as a human-readable string.
Use
isSchemaError
to narrow an unknown value to SchemaError.
Example (Catching a SchemaError)
import { Schema } from "effect"
try {
Schema.decodeUnknownSync(Schema.Number)("not a number")
} catch (err) {
if (Schema.isSchemaError(err)) {
console.log(err.message)
// Expected number, actual "not a number"
}
}
SchemaError extends import DataData.const TaggedError: <Tag extends string>(
tag: Tag
) => new <A extends Record<string, any> = {}>(
args: Types.VoidIfEmpty<{
readonly [P in keyof A as P extends "_tag"
? never
: P]: A[P]
}>
) => Cause.YieldableError & {
readonly _tag: Tag
} & Readonly<A>
Creates a tagged error class with a _tag discriminator.
When to use
Use when you need domain errors with discriminated-union handling.
Details
Like
Error
, but instances also carry a readonly _tag property,
enabling Effect.catchTag and Effect.catchTags for tag-based recovery.
The _tag is excluded from the constructor argument. Yielding an instance
inside Effect.gen fails the effect with this error.
Example (Recovering by tag)
import { Data, Effect } from "effect"
class NotFound extends Data.TaggedError("NotFound")<{
readonly resource: string
}> {}
class Forbidden extends Data.TaggedError("Forbidden")<{
readonly reason: string
}> {}
const program = Effect.gen(function*() {
return yield* new NotFound({ resource: "/users/42" })
})
const recovered = program.pipe(
Effect.catchTag("NotFound", (e) =>
Effect.succeed(`missing: ${e.resource}`))
)
TaggedError("SchemaError")<{
readonly issue: Issueissue: type Issue = Leaf | Filter | Encoding | Pointer | Composite | AnyOfThe 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.
Issue
}> {
readonly [const TypeId: "~effect/SchemaError/SchemaError"TypeId]: typeof const TypeId: "~effect/SchemaError/SchemaError"TypeId = const TypeId: "~effect/SchemaError/SchemaError"TypeId
constructor(issue: Issueissue: type Issue = Leaf | Filter | Encoding | Pointer | Composite | AnyOfThe 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.
Issue) {
super({ issue: Issueissue })
}
override get SchemaError.message: stringmessage() {
return this.issue: Issueissue.Base.toString(this: Issue): stringtoString()
}
override SchemaError.toString(): stringtoString() {
return `SchemaError(${this.SchemaError.message: stringmessage})`
}
}