{"record":{"id":"005e9af2fc8ec457","repo":"heygen-com/hyperframes","slug":"motiontogsap-invalid-track-track-property-v","errorCode":null,"errorMessage":"motionToGsap: invalid track \"${track.property}\" (values/times mismatch)","messagePattern":"motionToGsap: invalid track \"(.+?)\" \\(values/times mismatch\\)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/figma/motionToGsap.ts","lineNumber":75,"sourceCode":"    const value = track.values[i];\n    if (tPrev === undefined || tCur === undefined || value === undefined) continue;\n\n    const rawEase = track.ease[i - 1] ?? \"linear\";\n    const ease = resolveStepEase(rawEase, customEases, counter);\n    steps.push({ value, duration: (tCur - tPrev) * track.duration, ease });\n  }\n\n  return steps;\n}\n\nfunction buildTween(\n  track: MotionTrack,\n  selector: string,\n  customEases: CustomEaseRef[],\n  counter: CustomEaseCounter,\n): GsapTween {\n  if (track.values.length < 2 || track.times.length !== track.values.length) {\n    throw new Error(`motionToGsap: invalid track \"${track.property}\" (values/times mismatch)`);\n  }\n  const initial = track.values[0];\n  if (initial === undefined) throw new Error(`motionToGsap: empty track \"${track.property}\"`);\n\n  return {\n    selector,\n    property: track.property,\n    initial,\n    steps: buildSteps(track, customEases, counter),\n    repeat: clampRepeat(track.repeat),\n  };\n}\n\nexport function motionToGsap(doc: MotionDoc): TimelineSpec {\n  const customEases: CustomEaseRef[] = [];\n  const counter: CustomEaseCounter = { value: 0 };\n  const tweens = doc.tracks.map((track) => buildTween(track, doc.selector, customEases, counter));\n  return { timelineId: deriveId(doc.selector), tweens, customEases };","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/heygen-com/hyperframes/blob/c2996c8626135db5253519359d8a063d3bafad8d/packages/core/src/figma/motionToGsap.ts#L57-L93","documentation":"Thrown by buildTween when a MotionTrack is structurally invalid: either values.length < 2 (fewer than a start and end keyframe, so no tween exists) or times.length !== values.length (the time and value arrays disagree, so keyframe timing is ambiguous). motionToGsap cannot construct a GSAP keyframe sequence from such a track, and rather than emit a silent or misleading timeline it fails fast naming the offending property.","triggerScenarios":"A MotionTrack with values:[0.5] (single keyframe, no animation); values:[0,1] but times:[0] (mismatched lengths); a malformed motion.dev snippet parsed into a track with missing keyframes; hand-built MotionDoc where times/values arrays got out of sync.","commonSituations":"Parsing a figma motion snippet whose source had a single keyframe (no real animation); a refactored track builder that pushes to values but forgets times; an export tool emitting a 1-keyframe track for static properties instead of filtering it out.","solutions":["Filter out tracks with fewer than 2 keyframes before calling motionToGsap (static properties need no tween).","Ensure times and values arrays are always the same length when building a MotionTrack.","Inspect track.property in the error message to find which track is malformed, then fix its source.","If the track came from figma's get_motion_context, re-fetch the snippet — a partial response can truncate arrays."],"exampleFix":"// before — single keyframe track trips the guard\nconst track = { property: 'opacity', values: [1], times: [0], ease: [], duration: 1 };\n\n// after — drop static tracks before translating\nconst animatable = doc.tracks.filter((t) => t.values.length >= 2 && t.times.length === t.values.length);\nconst spec = motionToGsap({ ...doc, tracks: animatable });","handlingStrategy":"validation","validationCode":"import type { MotionTrack } from '.../figma/types';\nexport function isValidTrack(t: MotionTrack): boolean {\n  return t.values.length >= 2 && t.times.length === t.values.length;\n}\n// strip invalid tracks before motionToGsap\nconst validTracks = doc.tracks.filter(isValidTrack);\nif (validTracks.length === 0) throw new Error('no animatable tracks');\nconst spec = motionToGsap({ ...doc, tracks: validTracks });","typeGuard":"import type { MotionTrack } from '.../figma/types';\nexport function isAnimatableTrack(t: MotionTrack): t is MotionTrack {\n  return t.values.length >= 2 && t.times.length === t.values.length;\n}","tryCatchPattern":null,"preventionTips":["Filter single-keyframe tracks out of a MotionDoc before calling motionToGsap (they encode no motion).","When building MotionTracks, push to times and values together so lengths stay in sync.","If tracks come from figma's get_motion_context, validate them at the parser boundary."],"tags":["figma","motion","gsap","validation","animation"],"backgroundTag":null,"analyzedSha":"c2996c8626135db5253519359d8a063d3bafad8d","analyzedAt":"2026-08-12T22:18:56.877Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}