colinhacks/zod · error · Error
Key ${value} not found in enum
Error message
Key ${value} not found in enum What it means
Thrown by ZodEnum's `.extract(values)` method, which builds a new enum containing only the listed keys from the original enum's entries (schemas.ts:1941). If any value passed to `.extract()` is not an existing key in `def.entries`, the loop hits the `else` branch and throws. This is a construction-time guard ensuring the subset is valid, not a parse-time validation.
Source
Thrown at packages/zod/src/v4/classic/schemas.ts:1946
params?: string | core.$ZodEnumParams
): ZodEnum<util.Flatten<Omit<T, U[number]>>>;
}
export const ZodEnum: core.$constructor<ZodEnum> = /*@__PURE__*/ core.$constructor("ZodEnum", (inst, def) => {
core.$ZodEnum.init(inst, def);
ZodType.init(inst, def);
inst._zod.processJSONSchema = (ctx, json, params) => processors.enumProcessor(inst, ctx, json, params);
inst.enum = def.entries;
inst.options = Object.values(def.entries);
const keys = new Set(Object.keys(def.entries));
inst.extract = (values, params) => {
const newEntries: Record<string, any> = {};
for (const value of values) {
if (keys.has(value)) {
newEntries[value] = def.entries[value];
} else throw new Error(`Key ${value} not found in enum`);
}
return new ZodEnum({
...def,
checks: [],
...util.normalizeParams(params),
entries: newEntries,
}) as any;
};
inst.exclude = (values, params) => {
const newEntries: Record<string, any> = { ...def.entries };
for (const value of values) {
if (keys.has(value)) {
delete newEntries[value];
} else throw new Error(`Key ${value} not found in enum`);
}
return new ZodEnum({
...def,View on GitHub (pinned to 912f0f51b0)
Solutions
- Check the key exists first: `Object.keys(myEnum.enum).includes(value)` before calling `.extract()`.
- Fix the typo / casing so the value matches an actual key of the enum.
- Filter your input list against valid keys: `values.filter((v) => v in myEnum.enum)`.
- If the key was legitimately removed, update the call site to drop it from the extract list.
Example fix
// before const Primary = Colors.extract(["rede"]); // typo -> throws // after const Primary = Colors.extract(["red"]);
Defensive patterns
Strategy: validation
Validate before calling
const keys = Object.keys(myEnum.enum);
const want = ["red", "green"];
const missing = want.filter((k) => !keys.includes(k));
if (missing.length) throw new Error(`Unknown enum keys: ${missing.join(", ")}`);
const Primary = myEnum.extract(want); Type guard
// ZodEnum values are strings; guard the key list before extract.
function areEnumKeys<T extends Record<string, string>>(
e: T,
vals: readonly string[]
): vals is (keyof T)[] {
return vals.every((v) => v in e);
}
if (areEnumKeys(myEnum.enum, want)) myEnum.extract(want); Prevention
- Treat enum key lists as derived from `Object.keys(myEnum.enum)`, not hand-typed.
- Run a unit test that every key passed to `.extract()`/`.exclude()` exists in the source enum.
- When refactoring an enum, grep for `.extract(` and `.exclude(` usages of that enum.
When it happens
Trigger: Calling `myEnum.extract([...])` (or `.exclude`) with a key that is not present in `Object.keys(myEnum.enum)`. The check is `keys.has(value)` against the original enum's key set built at schemas.ts:1939.
Common situations: Refactoring an enum (renaming or removing a variant) and forgetting to update downstream `.extract()` calls; typos or wrong casing in keys; copy-pasting a key list from another enum; TS inference hiding the mismatch when the enum is typed as a wide Record.
Related errors
- Invalid UUID version: "${def.version}"
- Invalid element at key "${k}": expected a Zod schema
- Unrecognized key: "${key}"
AI-assisted analysis of colinhacks/zod@912f0f51b0 (2026-08-03).
Data as JSON: /data/errors/29d0494a8ef5b8e5.json.
Report an issue: GitHub.