colinhacks/zod · error · Error
This schema contains multiple valid literal values. Use `.va
Error message
This schema contains multiple valid literal values. Use `.values` instead.
What it means
In Zod v4 `z.literal()` accepts an array of values, producing a multi-value literal schema whose `.values` is a Set (schemas.ts:2016). The legacy single-value `.value` getter (schemas.ts:2017) throws when `def.values.length > 1` because a single value is ambiguous. The getter exists for backwards compatibility and explicitly redirects users to `.values`.
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 912f0f51b0)
Solutions
- Switch the read from `.value` to `.values` (a Set); use `[...schema.values][0]` if you specifically need one.
- If a single value is semantically required, construct with a scalar: `z.literal("a")` so `.value` stays valid.
- Guard the access: `if (schema.values.size === 1) { schema.value } else { ... }`.
Example fix
// before
const s = z.literal(["a", "b"]);
const v = s.value; // throws
// after
const s = z.literal(["a", "b"]);
const v = s.values; // Set { "a", "b" } Defensive patterns
Strategy: type-guard
Type guard
import { z } from "zod";
function isSingleValueLiteral(s: z.ZodLiteral<any>): boolean {
return s.values.size === 1;
}
const v = isSingleValueLiteral(schema) ? schema.value : schema.values; Prevention
- Prefer `.values` (Set) for any literal that could be multi-value.
- When migrating from v3, audit every `.value` read on literals.
- Construct with a scalar `z.literal(x)` when a single value is guaranteed.
When it happens
Trigger: Constructing `z.literal(["a", "b"])` (or any array with 2+ entries) then reading `.value` on the resulting schema. Also reachable by merging/concatenating literals into a multi-value one.
Common situations: Migrating Zod v3 code that read `.value` on literals; building a literal from a dynamically-sized array that happens to contain more than one element; refactoring a single-value literal into a union/multi form without updating `.value` accesses.
Related errors
- A discriminator value for key `${discriminator}` could not b
- Literal `undefined` cannot be represented in JSON Schema
- BigInt literals cannot be represented in JSON Schema
- Cannot create literal schema with no valid values
AI-assisted analysis of colinhacks/zod@912f0f51b0 (2026-08-03).
Data as JSON: /data/errors/71ef02a11f039a3e.json.
Report an issue: GitHub.