colinhacks/zod · error · Error
This schema contains multiple valid literal values. Use…
Error message
This schema contains multiple valid literal values. Use `.values` instead.
What it means
Thrown by the legacy `.value` getter on ZodLiteral when the literal schema was built from more than one value (z.literal([a, b, ...])). In Zod v4 a literal can accept an array of values and exposes them via `.values` (a Set); the single-value `.value` getter is kept only for backward compatibility and refuses to pick among multiple values.
Solutions
- Read from `.values` (a Set<T>) instead of `.value` for multi-value literals.
- If a single value is genuinely required, construct the literal with a scalar: z.literal('foo') rather than z.literal(['foo']).
- When you need the lone value but are unsure, guard with `schema.values.size === 1 ? [...schema.values][0] : undefined`.
Example fix
// before (throws — multiple values)
const lit = z.literal(['foo', 'bar']);
const v = lit.value;
// after
const lit = z.literal(['foo', 'bar']);
const vs = lit.values; // Set { 'foo', 'bar' } Defensive patterns
Strategy: type-guard
Type guard
function isSingleValueLiteral(schema) {
// ZodLiteral exposes .values as a Set in v4
return schema.values.size === 1;
}
// usage
const v = isSingleValueLiteral(lit) ? lit.value : lit.values; Try / catch
try {
const v = lit.value;
} catch (e) {
if (e.message.includes('multiple valid literal values')) {
const values = lit.values; // Set<T>
// handle multi-value case
} else {
throw e;
}
} Prevention
- Prefer `.values` (Set) when reading from literals that may have been built from arrays.
- Construct single-value literals with a scalar argument (z.literal(x)) when you intend to use `.value`.
- During Zod v3 -> v4 migration, audit every `.value` access on literal schemas.
When it happens
Trigger: Calling `.value` on a schema created with z.literal(['foo','bar']) or z.literal([1,2,3]). Migrating code from a single literal to a multi-value literal without switching property access.
Common situations: Upgrading from Zod v3 patterns where `.value` was the only accessor. Generalising a once-single literal into a union of literals and forgetting the read site.
Related errors
- A discriminator value for key
- Cannot create literal schema with no valid values
- Cannot specify both `message` and `error` params
- Invalid discriminated union option at index
- Key not found in enum
AI-assisted analysis of colinhacks/zod@2d90846af9 (2026-08-11).
Data as JSON: /api/errors/71ef02a11f039a3e.
Report an issue: GitHub.
Appendix: source
Thrown at packages/zod/src/v4/classic/schemas.ts:2020
// ZodLiteral
export interface ZodLiteral<T extends util.Literal = util.Literal>
extends _ZodType<core.$ZodLiteralInternals<T>>,
core.$ZodLiteral<T> {
"~standard": ZodStandardSchemaWithJSON<this>;
values: Set<T>;
/** @legacy Use `.values` instead. Accessing this property will throw an error if the literal accepts multiple values. */
value: T;
}
export const ZodLiteral: core.$constructor<ZodLiteral> = /*@__PURE__*/ core.$constructor("ZodLiteral", (inst, def) => {
core.$ZodLiteral.init(inst, def);
ZodType.init(inst, def);
inst._zod.processJSONSchema = (ctx, json, params) => processors.literalProcessor(inst, ctx, json, params);
inst.values = new Set(def.values);
Object.defineProperty(inst, "value", {
get() {
if (def.values.length > 1) {
throw new Error("This schema contains multiple valid literal values. Use `.values` instead.");
}
return def.values[0];
},
});
});
export function literal<const T extends ReadonlyArray<util.Literal>>(
value: T,
params?: string | core.$ZodLiteralParams
): ZodLiteral<T[number]>;
export function literal<const T extends util.Literal>(
value: T,
params?: string | core.$ZodLiteralParams
): ZodLiteral<T>;
export function literal(value: any, params: any) {
return new ZodLiteral({
type: "literal",
values: Array.isArray(value) ? value : [value],View on GitHub (pinned to 2d90846af9)