A Confect function can declare a typed error in its spec. When the handler fails with a value matching that schema, the error travels across the function boundary and surfaces—already decoded—at every call site (React hooks, JS clients, and tests). Typed errors are transported as Convex’s nativeDocumentation Index
Fetch the complete documentation index at: https://confect.dev/llms.txt
Use this file to discover all available pages before exploring further.
ConvexError, with the encoded error stored in ConvexError.data. The returns channel is left untouched, and non-Confect callers of the same Convex API see ordinary ConvexErrors. For mutations, throwing a ConvexError triggers Convex’s transaction rollback as usual.
Error schemas are optional. When omitted, the error type defaults to never and every call site keeps its prior shape.
Declaring an error schema
Add anerror field to any FunctionSpec constructor. The schema is an ordinary Effect Schema, so a Schema.TaggedError class works well for a single failure mode.
confect/notes.spec.ts
Schema.Union.
Failing from a handler
When a spec declares anerror schema, the corresponding FunctionImpl handler’s Effect error channel is typed as that schema’s Type. Use Effect.fail (or Effect.mapError) to fail with any value matching the schema.
confect/notes.impl.ts
error schema, the handler’s error channel is never and any unmapped failure must still be cleared (typically with Effect.orDie). With one, declared failures travel through, and any other failure (a defect) still rejects/dies as before.
Consuming typed errors
The decoded error is surfaced at every call site. The exact shape depends on the client.@confect/react
useQueryreturns aQueryResult<A, E>. Match it withQueryResult.match, whereonFailureis required when the ref declares anerrorschema.useMutationanduseActionreturnPromise<Either<A, E>>when the ref declares anerrorschema (andPromise<A>otherwise).
@confect/js
Both HttpClient and WebSocketClient add the decoded error to the returned Effect’s error channel, alongside the existing transport error and ParseError.
WebSocketClient.reactiveQuery carries typed errors too: when the subscribed query fails with a typed error, the returned Stream terminates with the decoded value in its error channel. See HTTP and WebSocket.
@confect/test
TestConfect’s query, mutation, and action decode typed errors into the Effect error channel, so test bridges see the same shape as the JS clients. See Testing.
Non-typed failures
Failures that are not declared in theerror schema are not silently swallowed. They propagate through Convex’s normal failure path: they reject promises in @convex/react, fail Effects with HttpClientError/WebSocketClientError in @confect/js, and surface as defects (cause) in TestConfect. Use a typed error schema for failures you want callers to handle, and let everything else die.