colinhacks/zod · error · Error
Can't use "invalid_type_error" or "required_error" in…
Error message
Can't use "invalid_type_error" or "required_error" in conjunction with custom error map.
What it means
Thrown by processCreateParams at packages/zod/src/v3/types.ts:127 when a schema factory is given both a custom errorMap AND either invalid_type_error or required_error in the same params object. These are two mutually exclusive ways to customize messages — errorMap is the general callback form, while invalid_type_error/required_error are shorthand shortcuts — so Zod refuses to guess which one wins. The check happens at schema construction time, before any data is parsed.
Solutions
- Pick one mechanism: keep errorMap and remove invalid_type_error/required_error from the params object.
- Or drop errorMap and use only invalid_type_error/required_error for the two targeted messages.
- If you need both targeted messages and a custom map, fold the special-case logic into your errorMap callback (branch on iss.code === 'invalid_type' and typeof ctx.data === 'undefined').
- Audit the params object passed to the factory — including ones spread from a shared config — for leftover shorthand keys.
Example fix
// before
const schema = z.string({
errorMap: myErrorMap,
invalid_type_error: 'Expected a string',
required_error: 'String is required',
});
// after (fold logic into the error map)
const schema = z.string({
errorMap: (iss, ctx) => {
if (iss.code === 'invalid_type') return { message: 'Expected a string' };
if (typeof ctx.data === 'undefined') return { message: 'String is required' };
return { message: ctx.defaultError };
},
}); Defensive patterns
Strategy: validation
Validate before calling
import type { RawCreateParams } from 'zod';
function assertCleanParams(params: RawCreateParams): RawCreateParams {
if (!params) return params;
const hasShorthand = 'invalid_type_error' in params || 'required_error' in params;
const hasErrorMap = 'errorMap' in params && params.errorMap !== undefined;
if (hasShorthand && hasErrorMap) {
throw new Error('Refusing to pass both errorMap and shorthand messages to Zod; remove one.');
}
return params;
}
// usage: z.string(assertCleanParams(config)); Type guard
function hasConflictingErrorParams(p: unknown): p is { errorMap: unknown; invalid_type_error?: unknown; required_error?: unknown } {
if (!p || typeof p !== 'object') return false;
const o = p as Record<string, unknown>;
const hasMap = typeof o.errorMap !== 'undefined';
const hasShorthand = typeof o.invalid_type_error !== 'undefined' || typeof o.required_error !== 'undefined';
return hasMap && hasShorthand;
} Try / catch
null
Prevention
- Adopt one error-customisation style per schema: either errorMap OR shorthand messages, never both.
- When spreading a shared config object into schema params, audit it for leftover shorthand keys.
- Centralise error-message config in a factory so the conflict can't arise ad hoc.
- Treat errorMap as the upgrade path: when you need more than invalid_type/required messages, migrate fully to errorMap.
When it happens
Trigger: Calling a schema factory like `z.string({ errorMap: myMap, invalid_type_error: '...' })` or `z.object({...}, { errorMap: myMap, required_error: '...' })` — i.e. passing both errorMap and one of the shorthand message options together in the second-argument params.
Common situations: Adding invalid_type_error/required_error to an existing schema that already uses a global or local errorMap; copy-pasting params from another schema that had an errorMap; migrating from per-field messages to a shared errorMap and leaving the shorthand keys behind; using z.setErrorMap globally and then also passing shorthand params.
Related errors
- A discriminator value for key
- Cannot create literal schema with no valid values
- Cannot specify both `message` and `error` params
- Discriminator property
- Duplicate discriminator value
AI-assisted analysis of colinhacks/zod@2d90846af9 (2026-08-11).
Data as JSON: /api/errors/f83bba4bec81e8c0.
Report an issue: GitHub.
Appendix: source
Thrown at packages/zod/src/v3/types.ts:127
export type RawCreateParams =
| {
errorMap?: ZodErrorMap | undefined;
invalid_type_error?: string | undefined;
required_error?: string | undefined;
message?: string | undefined;
description?: string | undefined;
}
| undefined;
export type ProcessedCreateParams = {
errorMap?: ZodErrorMap | undefined;
description?: string | undefined;
};
function processCreateParams(params: RawCreateParams): ProcessedCreateParams {
if (!params) return {};
const { errorMap, invalid_type_error, required_error, description } = params;
if (errorMap && (invalid_type_error || required_error)) {
throw new Error(`Can't use "invalid_type_error" or "required_error" in conjunction with custom error map.`);
}
if (errorMap) return { errorMap: errorMap, description };
const customMap: ZodErrorMap = (iss, ctx) => {
const { message } = params;
if (iss.code === "invalid_enum_value") {
return { message: message ?? ctx.defaultError };
}
if (typeof ctx.data === "undefined") {
return { message: message ?? required_error ?? ctx.defaultError };
}
if (iss.code !== "invalid_type") return { message: ctx.defaultError };
return { message: message ?? invalid_type_error ?? ctx.defaultError };
};
return { errorMap: customMap, description };
}
export type SafeParseSuccess<Output> = {View on GitHub (pinned to 2d90846af9)