{"record":{"id":"d617174cf2edf996","repo":"remotion-dev/remotion","slug":"could-not-add-effect-keyframe","errorCode":null,"errorMessage":"Could not add effect keyframe","messagePattern":"Could not add effect keyframe","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/browser-studio/src/browser-studio-operations.ts","lineNumber":1614,"sourceCode":"\t\t\t\t\t\tsequenceNodePath: request.sequenceNodePath,\n\t\t\t\t\t\teffectIndex: request.effectIndex,\n\t\t\t\t\t\tschema: request.schema,\n\t\t\t\t\t\tupdates: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tkey: request.key,\n\t\t\t\t\t\t\t\toperation: {\n\t\t\t\t\t\t\t\t\ttype: 'add',\n\t\t\t\t\t\t\t\t\tframe: request.frame,\n\t\t\t\t\t\t\t\t\tvalue: JSON.parse(request.value),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t});\n\t\t\tconst mutation = result.appliedEffectMutations[0];\n\t\t\tif (!mutation) {\n\t\t\t\tthrow new Error('Could not add effect keyframe');\n\t\t\t}\n\n\t\t\treturn getEffectKeyframeResponse({mutation, project: result.project});\n\t\t},\n\t\taddKeyframes: async ({sequenceKeyframes, effectKeyframes}) => {\n\t\t\tawait commitKeyframeMutations({\n\t\t\t\tlabel: `${sequenceKeyframes.length + effectKeyframes.length} keyframes`,\n\t\t\t\tsequenceMutations: sequenceKeyframes.map((keyframe) => ({\n\t\t\t\t\tfileName: keyframe.fileName,\n\t\t\t\t\tnodePath: keyframe.nodePath,\n\t\t\t\t\tschema: keyframe.schema,\n\t\t\t\t\tupdates: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tkey: keyframe.key,\n\t\t\t\t\t\t\toperation: {\n\t\t\t\t\t\t\t\ttype: 'add',\n\t\t\t\t\t\t\t\tframe: keyframe.frame,\n\t\t\t\t\t\t\t\tvalue: JSON.parse(keyframe.value),","sourceCodeStart":1596,"sourceCodeEnd":1632,"githubUrl":"https://github.com/remotion-dev/remotion/blob/b2f4e34732f3c6c222ea029413e22dc402218cd7/packages/browser-studio/src/browser-studio-operations.ts#L1596-L1632","documentation":"Rejected by addEffectKeyframe in @remotion/browser-studio when `result.appliedEffectMutations[0]` is undefined after commitKeyframeMutations — the 'add' mutation targeting a specific effect on a sequence was not applied. The target is addressed by the triple (fileName, sequenceNodePath, effectIndex), so any of those being stale makes the mutation a no-op and the promise rejects.","triggerScenarios":"Calling `keyframes.addEffectKeyframe({fileName, sequenceNodePath, effectIndex, schema, key, frame, value})` where the sequence node no longer exists, the effectIndex no longer points at the intended effect (effects were added/removed/reordered), or the schema does not match the effect's parameter schema.","commonSituations":"Effect list changed between when the user selected an effect and clicked to keyframe it; node paths stale after an undo/redo; effectIndex computed from an older render of the timeline.","solutions":["Re-resolve sequenceNodePath and the current effectIndex from the latest project state and retry","Verify the effect still exists at effectIndex on the target sequence node","Ensure `value` is valid JSON matching the parameter type","Catch the rejection and refresh the effects panel before letting the user retry"],"exampleFix":"// before\nawait operations.keyframes.addEffectKeyframe({\n  fileName,\n  sequenceNodePath: stale,\n  effectIndex: 0,\n  schema: staleSchema,\n  key: ' intensity',\n  frame: 10,\n  value: '1',\n});\n\n// after\nconst {nodePath, effectIndex, schema} = await resolveCurrentEffectTarget();\ntry {\n  await operations.keyframes.addEffectKeyframe({\n    fileName,\n    sequenceNodePath: nodePath,\n    effectIndex,\n    schema,\n    key: 'intensity',\n    frame: 10,\n    value: JSON.stringify(1),\n  });\n} catch {\n  await refreshEffects();\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await operations.keyframes.addEffectKeyframe({fileName, sequenceNodePath, effectIndex, schema, key, frame, value});\n} catch (error) {\n  await refreshEffects(); // effectIndex/paths shifted\n  showRetryToast();\n}","preventionTips":["Recompute effectIndex from the current effect list right before the call","After adding/removing effects on a node, invalidate cached effect indexes","JSON.stringify values client-side instead of hand-building JSON strings"],"tags":["keyframes","effects","node-path","browser-studio"],"backgroundTag":"invalid-node-path","analyzedSha":"b2f4e34732f3c6c222ea029413e22dc402218cd7","analyzedAt":"2026-08-22T21:45:17.748Z","contentChangedAt":"2026-08-22T21:45:17.748Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}