{"record":{"id":"57e0c57ec1df32b5","repo":"remotion-dev/remotion","slug":"name-must-be-formatenum-variants-but-got","errorCode":null,"errorMessage":"\"${name}\" must be ${formatEnum(variants)}, but got ${JSON.stringify(value)}","messagePattern":"\"(.+?)\" must be (.+?), but got (.+?)","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/effects/src/evolve.ts","lineNumber":87,"sourceCode":"\t}\n\n\treturn `${variants\n\t\t.slice(0, -1)\n\t\t.map((variant) => `\"${variant}\"`)\n\t\t.join(', ')} or \"${variants[variants.length - 1]}\"`;\n};\n\nconst assertOptionalEnum = <T extends string>(\n\tvalue: unknown,\n\tname: string,\n\tvariants: readonly T[],\n): void => {\n\tif (value === undefined) {\n\t\treturn;\n\t}\n\n\tif (!variants.includes(value as T)) {\n\t\tthrow new TypeError(\n\t\t\t`\"${name}\" must be ${formatEnum(variants)}, but got ${JSON.stringify(value)}`,\n\t\t);\n\t}\n};\n\nconst resolve = (p: EvolveParams): EvolveResolved => ({\n\tprogress: p.progress ?? DEFAULT_PROGRESS,\n\tdirection: p.direction ?? DEFAULT_DIRECTION,\n\tfeather: p.feather ?? DEFAULT_FEATHER,\n});\n\nconst validateEvolveParams = (params: EvolveParams): void => {\n\tassertEffectParamsObject(params, 'Evolve');\n\tassertOptionalFiniteNumber(params.progress, 'progress');\n\tassertOptionalFiniteNumber(params.feather, 'feather');\n\tassertOptionalEnum(params.direction, 'direction', EVOLVE_DIRECTIONS);\n\n\tconst r = resolve(params);","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/effects/src/evolve.ts#L69-L105","documentation":"Thrown by the evolve effect's assertOptionalEnum() (a TypeError) when a `direction` value is supplied but is not one of the four allowed variants 'left' | 'right' | 'top' | 'bottom'. The check is skipped when direction is undefined (the default 'left' applies), so it only fires for a present-but-invalid string. The message lists the allowed variants via formatEnum().","triggerScenarios":"Calling evolve({direction: 'Left'}), evolve({direction: 'CENTER'}), evolve({direction: 'up'}), or any other string outside the four literals. Common with case mismatches or typos.","commonSituations":"Wrong letter casing (the variants are lowercase), a typo, or a dynamically constructed direction string that does not match a variant exactly.","solutions":["Use one of the exact lowercase literals: 'left', 'right', 'top', or 'bottom'.","Type the prop against the exported EvolveDirection type so the compiler rejects invalid values.","If the direction comes from data, validate/match it against the allowed list before passing it in.","Omit direction to accept the default 'left'."],"exampleFix":"// before\nevolve({progress: 0.5, direction: 'Left'})\n\n// after\nimport {type EvolveDirection} from '@remotion/effects';\nevolve({progress: 0.5, direction: 'left'})","handlingStrategy":"validation","validationCode":"import {type EvolveDirection} from '@remotion/effects';\n\nconst EVOLVE_DIRECTIONS = ['left', 'right', 'top', 'bottom'] as const;\n\nfunction normalizeDirection(value: string): EvolveDirection | null {\n  const match = EVOLVE_DIRECTIONS.find((d) => d === value.toLowerCase());\n  return match ?? null;\n}\n\n// Validate before calling evolve():\nconst dir = normalizeDirection(userInput);\nif (!dir) throw new TypeError(`invalid direction: ${userInput}`);\nevolve({direction: dir});","typeGuard":"import {type EvolveDirection} from '@remotion/effects';\n\nconst EVOLVE_DIRECTIONS = ['left', 'right', 'top', 'bottom'] as const;\n\nfunction isEvolveDirection(v: unknown): v is EvolveDirection {\n  return typeof v === 'string' &&\n    (EVOLVE_DIRECTIONS as readonly string[]).includes(v);\n}","tryCatchPattern":null,"preventionTips":["Always use the lowercase literals: 'left', 'right', 'top', 'bottom'.","Type the prop as EvolveDirection so the compiler rejects invalid values.","Normalize external strings (lowercase) and validate membership before passing them in.","Omit direction to accept the default 'left'."],"tags":["validation","typescript","effects","params","enum"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}