{"record":{"id":"ac5dc2af09b50768","repo":"remotion-dev/remotion","slug":"the-start-and-end-values-must-be-of-the-same-type","errorCode":null,"errorMessage":"The start and end values must be of the same type. Start value: ${initialStyleProperty}, end value: ${finalStyleProperty}","messagePattern":"The start and end values must be of the same type\\. Start value: (.+?), end value: (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/animation-utils/src/transformation-helpers/interpolate-styles/index.tsx","lineNumber":42,"sourceCode":"const interpolatedPropertyPart = ({\n\tinputValue,\n\tinputRange,\n\tinitialStylePropertyPart,\n\tfinalStylePropertyPart,\n\tinitialStyleProperty,\n\tfinalStyleProperty,\n\toptions,\n}: {\n\tinputValue: number;\n\tinputRange: number[];\n\tinitialStylePropertyPart: UnitNumberAndFunction;\n\tfinalStylePropertyPart: UnitNumberAndFunction;\n\tinitialStyleProperty: CSSPropertiesValue;\n\tfinalStyleProperty: CSSPropertiesValue;\n\toptions: InterpolateStylesResolvedOptions;\n}): string | number => {\n\tif (finalStylePropertyPart === undefined) {\n\t\tthrow new TypeError(\n\t\t\t`The start and end values must be of the same type. Start value: ${initialStyleProperty}, end value: ${finalStyleProperty}`,\n\t\t);\n\t}\n\n\tif (initialStylePropertyPart.color) {\n\t\tif (!finalStylePropertyPart.color) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`The start and end values must be of the same type. Start value: ${initialStyleProperty}, end value: ${finalStyleProperty}`,\n\t\t\t);\n\t\t}\n\n\t\tconst interpolatedColor = interpolateColors(inputValue, inputRange, [\n\t\t\tinitialStylePropertyPart.color,\n\t\t\tfinalStylePropertyPart.color as string,\n\t\t]);\n\t\treturn `${interpolatedColor}`;\n\t}\n","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/animation-utils/src/transformation-helpers/interpolate-styles/index.tsx#L24-L60","documentation":"Thrown by interpolateStyles inside interpolatedPropertyPart when the end-side decomposed part is undefined while interpolating a CSS value. This happens when a CSS function in the start value has more arguments than the same-named function in the end value (e.g. translate(10px, 20px) vs translate(10px)), so there is no end token to interpolate toward.","triggerScenarios":"outputStyles keyframes where a transform function carries a different argument count on each side: start {transform: 'translate(100px, 50px)'} (2 args) to end {transform: 'translate(200px)'} (1 arg); or a function arg present on one side and absent on the other.","commonSituations":"Authoring keyframes incrementally and forgetting the second coordinate; refactoring a transform and dropping an argument in one keyframe; copy-pasting shorthand values that decompose asymmetrically.","solutions":["Give the same-named CSS function the same argument count in every keyframe (pad missing args with identity values like 0px).","Keep the structure of every multi-part value identical across all outputStyles entries.","If argument counts must differ, split into separate interpolated properties rather than one transform string."],"exampleFix":"// before\ninterpolateStyles(frame, [0, 30], [\n  {transform: 'translate(100px, 50px)'},\n  {transform: 'translate(200px)'},  // missing 2nd arg\n]);\n\n// after\ninterpolateStyles(frame, [0, 30], [\n  {transform: 'translate(100px, 50px)'},\n  {transform: 'translate(200px, 0px)'},\n]);","handlingStrategy":"validation","validationCode":"// Ensure each CSS function has the same argument count on both sides.\nconst argCount = (fn: string) => {\n  const inner = fn.slice(fn.indexOf('(') + 1, fn.lastIndexOf(')'));\n  return inner.trim() === '' ? 0 : inner.split(',').length;\n};\nconst sameFunctionShape = (a: string, b: string) =>\n  a.split(/\\s+/).every((part, i) => {\n    const bp = b.split(/\\s+/)[i];\n    return bp && part.split('(')[0] === bp.split('(')[0] && argCount(part) === argCount(bp);\n  });\n// usage: sameFunctionShape(startStyle.transform, endStyle.transform)","typeGuard":null,"tryCatchPattern":"// Fall back to the nearest keyframe style if interpolation is impossible.\nlet style: React.CSSProperties;\ntry {\n  style = interpolateStyles(frame, range, styles);\n} catch (e) {\n  if (e instanceof TypeError && /same type/.test(e.message)) {\n    style = frame < range[Math.floor(range.length / 2)] ? styles[0] : styles[styles.length - 1];\n  } else {\n    throw e;\n  }\n}","preventionTips":["Keep transform strings structurally identical across all keyframes (same functions, same arg counts).","Pad missing function arguments with identity values (0px, 0deg) so counts match.","Add a unit test that asserts every keyframe's transform has the same decomposed shape."],"tags":["interpolate-styles","transform","validation","css"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}