{"record":{"id":"e861c333bb3087f0","repo":"remotion-dev/remotion","slug":"cannot-interpolate-value-because-first","errorCode":null,"errorMessage":"Cannot interpolate \"${value}\" because \"${first} ${second}\" is not a valid transform-origin keyword pair","messagePattern":"Cannot interpolate \"(.+?)\" because \"(.+?) (.+?)\" is not a valid transform-origin keyword pair","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/core/src/interpolate.ts","lineNumber":260,"sourceCode":"\tvalue: string,\n): [TransformOriginAxisValue, TransformOriginAxisValue] => {\n\tconst candidates: [TransformOriginAxisValue, TransformOriginAxisValue][] = [];\n\tfor (const firstOption of transformOriginKeywordOptions(first)) {\n\t\tfor (const secondOption of transformOriginKeywordOptions(second)) {\n\t\t\tif (firstOption.axis === secondOption.axis) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tcandidates.push(\n\t\t\t\tfirstOption.axis === 'x'\n\t\t\t\t\t? [firstOption.value, secondOption.value]\n\t\t\t\t\t: [secondOption.value, firstOption.value],\n\t\t\t);\n\t\t}\n\t}\n\n\tif (candidates.length === 0) {\n\t\tthrow new TypeError(\n\t\t\t`Cannot interpolate \"${value}\" because \"${first} ${second}\" is not a valid transform-origin keyword pair`,\n\t\t);\n\t}\n\n\treturn candidates[0];\n};\n\nconst parseTransformOriginXY = (\n\tparts: string[],\n\tvalue: string,\n): [TransformOriginAxisValue, TransformOriginAxisValue] => {\n\tif (parts.length === 1) {\n\t\tconst token = parseTransformOriginToken(parts[0], value);\n\t\tif (token.type === 'length-percentage') {\n\t\t\treturn [token.parsed, transformOriginCenter];\n\t\t}\n\n\t\tif (token.keyword === 'top' || token.keyword === 'bottom') {","sourceCodeStart":242,"sourceCodeEnd":278,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/core/src/interpolate.ts#L242-L278","documentation":"Thrown by parseTwoTransformOriginKeywords when a two-keyword transform-origin pair resolves to zero valid candidates, i.e. both keywords target the same axis. left/right are x-only, top/bottom are y-only; pairing two from the same group leaves no cross-axis candidate so the value is ambiguous and rejected.","triggerScenarios":"A two-component transform-origin string where both tokens are keywords on the same axis: \"left right\", \"right left\", \"top bottom\", \"bottom top\".","commonSituations":"Authoring a transform-origin with two horizontal or two vertical keywords by mistake; copy-pasting CSS that relied on a different interpretation.","solutions":["Pair one horizontal keyword with one vertical keyword: \"left top\", \"right bottom\", \"center center\".","Replace one keyword with an explicit length: \"left 50%\"."],"exampleFix":"// before\ninterpolate(t, [0, 1], [\"left right\", \"center center\"]);\n// after\ninterpolate(t, [0, 1], [\"left top\", \"center center\"]);","handlingStrategy":"validation","validationCode":"const xKeys = new Set(['left', 'right']);\nconst yKeys = new Set(['top', 'bottom']);\n\nfunction isValidTwoKeywordPair(a: string, b: string): boolean {\n  const A = a.toLowerCase(), B = b.toLowerCase();\n  if (A === 'center' || B === 'center') return true;\n  const aX = xKeys.has(A), aY = yKeys.has(A);\n  const bX = xKeys.has(B), bY = yKeys.has(B);\n  return (aX && bY) || (aY && bX);\n}\n\nconst parts = output.trim().split(/\\s+/);\nif (parts.length === 2 && parts.every((p) => /^(left|right|top|bottom|center)$/i.test(p))) {\n  if (!isValidTwoKeywordPair(parts[0], parts[1])) throw new Error('Same-axis keyword pair');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pair one horizontal (left/right/center) with one vertical (top/bottom/center) keyword.","Avoid \"left right\" and \"top bottom\" pairs.","When unsure, use explicit percentages like \"0% 0%\"."],"tags":["interpolate","transform-origin","keywords","validation"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}