Runtime Validation
defineJobTypes gives you compile-time type safety with zero runtime cost. When job inputs come from outside your program — HTTP handlers, dashboards, cross-service cron payloads — TypeScript can’t reject a malformed value before your handler runs. createJobTypes closes that gap: it accepts validation callbacks that run at every boundary the library touches (entry, input, output, continuation, blockers).
When to use it
Section titled “When to use it”Reach for createJobTypes when inputs cross a trust boundary, or when you already depend on a schema library (Zod, Valibot, TypeBox, ArkType) and want the same schemas to guard your jobs. Stick with defineJobTypes when every caller is internal code TypeScript already checks.
You typically don’t call createJobTypes directly — you go through a thin schema-library adapter that infers TJobTypeDefinitions from your schemas and wires them into the validation callbacks. The Zod version looks like this:
import { createClient } from "queuert";import { z } from "zod";
import { createZodJobTypes } from "./zod-adapter.js";
const jobTypes = createZodJobTypes({ "send-email": { entry: true, input: z.object({ to: z.string(), subject: z.string(), body: z.string() }), output: z.object({ messageId: z.string() }), },});
const client = await createClient({ stateAdapter, notifyAdapter, jobTypes });Handlers keep full type inference — job.input is typed from the Zod schema. The adapter itself is ~60 lines; copy it from examples/validation-zod or pick another library from the integration page.
How errors surface
Section titled “How errors surface”A failed validation throws JobTypeValidationError. A code identifies which boundary rejected the value, and typeName identifies the job type:
import { JobTypeValidationError } from "queuert";
try { await stateAdapter.withTransaction((ctx) => client.startChain({ ...ctx, transactionHooks, typeName: "send-email", input: untrusted }), );} catch (err) { if (err instanceof JobTypeValidationError && err.code === "invalid_input") { // 400 to the caller — the payload was malformed }}Errors thrown by the underlying schema library (ZodError, ValiError, TypeBoxError, …) are caught and wrapped, so callers always handle a single error type regardless of which library the adapter uses. The five codes are not_entry_point, invalid_input, invalid_output, invalid_continuation, and invalid_blockers.
See also
Section titled “See also”- Validation Adapters — the adapter pattern, the six-method contract, and ready-to-copy adapters for Zod, Valibot, TypeBox, and ArkType
- Custom Adapters — building and conformance-testing your own validation adapter
- Error Handling — how
JobTypeValidationErrorinteracts with retries and chain failure