colinhacks/zod · error · Error
Cannot create literal schema with no valid values
Error message
Cannot create literal schema with no valid values
What it means
Thrown by the $ZodLiteral constructor when def.values.length === 0. A literal schema must enumerate at least one concrete value to match against; an empty literal set has nothing to accept and would silently reject every input, so construction fails. The public z.literal() API normally guarantees a non-empty array, so this typically surfaces through direct internal construction, a buggy wrapper, or an empty spread.
Solutions
- Ensure the values array passed to z.literal() contains at least one entry.
- Guard dynamic generators: if (values.length === 0) throw or fall back to z.never()/z.unknown().
- Validate configuration upstream so empty allow-lists are caught with a clearer error.
- Unit-test the generator against an empty input.
Example fix
// before const L = z.literal([...allowed]); // allowed is [] // after const L = allowed.length ? z.literal([...allowed]) : z.never();
Defensive patterns
Strategy: validation
Validate before calling
function safeLiteral(values: util.Literal[]) {
if (!Array.isArray(values) || values.length === 0) {
return z.never();
}
return z.literal(values);
} Type guard
function hasValues(values: unknown): values is [unknown, ...unknown[]] {
return Array.isArray(values) && values.length > 0;
} Prevention
- Validate dynamic value lists are non-empty before passing to z.literal().
- Provide a fallback (z.never() or z.unknown()) when the list could be empty.
- Add a unit test for the empty-list case in any schema factory.
When it happens
Trigger: Calling z.literal([]) or constructing $ZodLiteral with { values: [] }; spreading an empty array into z.literal(...[]); dynamically building a literal from a list that turned out empty; a custom helper that forwards user input to def.values without checking length.
Common situations: Generating literal schemas from configuration data (an empty allow-list at config time); refactoring enums to literals and forgetting a fallback; user-driven feature flags that produce no values; off-by-one filters that strip every element.
Related errors
- A discriminator value for key
- Invalid discriminated union option at index
- Invalid UUID version
- This schema contains multiple valid literal values. Use…
- Unrecognized hash format
AI-assisted analysis of colinhacks/zod@2d90846af9 (2026-08-11).
Data as JSON: /api/errors/759c2140359c9e92.
Report an issue: GitHub.
Appendix: source
Thrown at packages/zod/src/v4/core/schemas.ts:3296
}
export interface $ZodLiteralInternals<T extends util.Literal = util.Literal> extends $ZodTypeInternals<T, T> {
def: $ZodLiteralDef<T>;
values: Set<T>;
pattern: RegExp;
isst: errors.$ZodIssueInvalidValue;
}
export interface $ZodLiteral<T extends util.Literal = util.Literal> extends $ZodType {
_zod: $ZodLiteralInternals<T>;
}
export const $ZodLiteral: core.$constructor<$ZodLiteral> = /*@__PURE__*/ core.$constructor(
"$ZodLiteral",
(inst, def) => {
$ZodType.init(inst, def);
if (def.values.length === 0) {
throw new Error("Cannot create literal schema with no valid values");
}
const values = new Set<util.Literal>(def.values);
inst._zod.values = values;
inst._zod.pattern = new RegExp(
`^(${def.values
.map((o) => (typeof o === "string" ? util.escapeRegex(o) : o ? util.escapeRegex(o.toString()) : String(o)))
.join("|")})$`
);
inst._zod.parse = (payload, _ctx) => {
const input = payload.value;
if (values.has(input)) {
return payload;
}
payload.issues.push({
code: "invalid_value",View on GitHub (pinned to 2d90846af9)