{"record":{"id":"e42081f9dfbd4630","repo":"airbnb/lottie-web","slug":"the-property-has-no-keyframe-at-index-ind","errorCode":null,"errorMessage":"The property has no keyframe at index {ind}","messagePattern":"The property has no keyframe at index (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"player/js/utils/expressions/ExpressionManager.js","lineNumber":601,"sourceCode":"          }\n          if (index === -1) {\n            index = iKey + 1;\n            keyTime = data.k[iKey].t;\n          }\n        }\n      }\n      var obKey = {};\n      obKey.index = index;\n      obKey.time = keyTime / elem.comp.globalData.frameRate;\n      return obKey;\n    }\n\n    function key(ind) {\n      var obKey;\n      var iKey;\n      var lenKey;\n      if (!data.k.length || typeof (data.k[0]) === 'number') {\n        throw new Error('The property has no keyframe at index ' + ind);\n      }\n      ind -= 1;\n      obKey = {\n        time: data.k[ind].t / elem.comp.globalData.frameRate,\n        value: [],\n      };\n      var arr = Object.prototype.hasOwnProperty.call(data.k[ind], 's') ? data.k[ind].s : data.k[ind - 1].e;\n\n      lenKey = arr.length;\n      for (iKey = 0; iKey < lenKey; iKey += 1) {\n        obKey[iKey] = arr[iKey];\n        obKey.value[iKey] = arr[iKey];\n      }\n      return obKey;\n    }\n\n    function framesToTime(fr, fps) {\n      if (!fps) {","sourceCodeStart":583,"sourceCodeEnd":619,"githubUrl":"https://github.com/airbnb/lottie-web/blob/bede03d25d232826e0c9dca1733d542d8a7754fb/player/js/utils/expressions/ExpressionManager.js#L583-L619","documentation":"Thrown inside the expression engine's key(ind) accessor. key() indexes the property's keyframe array data.k. If data.k has no entries, or its first element is a plain number, the property is NOT keyframed (it holds a single static value) and therefore has no keyframes to index — so calling key(n) is invalid. The guard fires before any indexing, so the error message echoes the requested index.","triggerScenarios":"An After Effects expression calls property.key(n) (or numKeys-aware logic that still reaches key()) on a property that was never keyframed — i.e. its value is a constant. Also when the expression assumes keyframes exist but the source property was left static in the comp.","commonSituations":"Authoring expressions that call key() without first checking numKeys; reusing an expression written for an animated property on a static one; Lottie files where a property's keyframes were baked to a single value on export; referencing a control (e.g. a slider) that has no keyframes.","solutions":["Guard the expression: only call key() when property.numKeys > 0.","Add at least two keyframes to the property in After Effects so data.k becomes a keyframe array.","Wrap the key() access in a try/catch inside the expression and fall back to the property's static value."],"exampleFix":"// before (AE expression)\nvar k = thisProperty.key(1);\n// after\nvar k = (thisProperty.numKeys > 0) ? thisProperty.key(1) : thisProperty.value;","handlingStrategy":"validation","validationCode":"// Inside the After Effects expression, guard before indexing keyframes:\n// (numKeys is provided by the expression interface for animated properties)\n// return (thisProperty.numKeys > 0) ? thisProperty.key(1).value : thisProperty.value;","typeGuard":"// Expression guard — only call key() on keyframed properties:\n// typeof thisProperty.numKeys === 'number' && thisProperty.numKeys > 0","tryCatchPattern":"// In an AE expression, fall back to the static value if key() is unavailable:\n// var v;\n// try { v = thisProperty.key(ind).value; }\n// catch (e) { v = thisProperty.value; }\n// v","preventionTips":["Always check thisProperty.numKeys > 0 before calling key().","Do not reuse animated-property expressions on static properties without a guard.","Verify on export that properties referenced by key()-based expressions are actually keyframed."],"tags":["lottie","expressions","after-effects","keyframes","animation-data"],"backgroundTag":null,"analyzedSha":"bede03d25d232826e0c9dca1733d542d8a7754fb","analyzedAt":"2026-08-13T05:40:22.197Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}