colinhacks/zod · error · Error
implementAsync() must be called with a function
Error message
implementAsync() must be called with a function
What it means
Thrown by `inst.implementAsync(func)` on a `z.function()` schema when the argument is not a function. `.implementAsync()` is the async variant of `.implement()`, returning an async function whose arguments/return are parsed with `parseAsync`; it still requires a function argument to wrap.
Source
Thrown at packages/zod/src/v4/core/schemas.ts:4446
inst._zod.def = def;
inst.implement = (func) => {
if (typeof func !== "function") {
throw new Error("implement() must be called with a function");
}
return function (this: any, ...args: never[]) {
const parsedArgs = inst._def.input ? parse(inst._def.input, args) : args;
const result = Reflect.apply(func, this, parsedArgs as never[]);
if (inst._def.output) {
return parse(inst._def.output, result);
}
return result as any;
};
};
inst.implementAsync = (func) => {
if (typeof func !== "function") {
throw new Error("implementAsync() must be called with a function");
}
return async function (this: any, ...args: never[]) {
const parsedArgs = inst._def.input ? await parseAsync(inst._def.input, args) : args;
const result = await Reflect.apply(func, this, parsedArgs as never[]);
if (inst._def.output) {
return await parseAsync(inst._def.output, result);
}
return result;
} as any;
};
inst._zod.parse = (payload, _ctx) => {
if (typeof payload.value !== "function") {
payload.issues.push({
code: "invalid_type",
expected: "function",
input: payload.value,
inst,View on GitHub (pinned to 912f0f51b0)
Solutions
- Pass a function (sync or async) to `.implementAsync()`, e.g. `schema.implementAsync(async (arg) => ...)`.
- Guard dynamically: `if (typeof handler === 'function') schema.implementAsync(handler)`.
- Verify the handler is defined at the call site (check imports and initialization order).
Example fix
// before const fn = z.function(z.string(), z.boolean()).implementAsync(undefined); // after const fn = z.function(z.string(), z.boolean()).implementAsync(async (s) => !!s);
Defensive patterns
Strategy: type-guard
Validate before calling
if (typeof handler !== 'function') throw new Error('handler must be a function');
const wrapped = fnSchema.implementAsync(handler); Type guard
function isFunction(v): boolean { return typeof v === 'function'; } Try / catch
try {
const wrapped = fnSchema.implementAsync(handler);
} catch (e) {
if (e instanceof Error && e.message === 'implementAsync() must be called with a function') {
// confirm handler is a function and retry
}
throw e;
} Prevention
- Type the handler as a function parameter to get compile-time safety.
- Guard conditionally-defined async handlers with typeof checks.
- Check that the handler import resolves (no circular-import undefined).
When it happens
Trigger: Calling `.implementAsync(undefined)`, `.implementAsync(null)`, `.implementAsync('handler')`, or any non-function value. Same shape as the sync variant.
Common situations: Mistakenly passing a promise or a config object; handler variable is undefined due to a circular import or hoisting issue.
Related errors
- implement() must be called with a function
- Synchronous parse encountered promise.
- Async refinement encountered during synchronous parse operat
- Asynchronous transform encountered during synchronous parse
- Async schemas not supported in object keys currently
AI-assisted analysis of colinhacks/zod@912f0f51b0 (2026-08-03).
Data as JSON: /data/errors/d159ed4c30b915ea.json.
Report an issue: GitHub.