{"record":{"id":"e1d3622f61637f79","repo":"Unity-Technologies/UnityCsReference","slug":"allowed-errors-for-keyframe-reduction-cannot-be-ne","errorCode":null,"errorMessage":"Allowed errors for keyframe reduction cannot be negative.","messagePattern":"Allowed errors for keyframe reduction cannot be negative\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"Editor/Mono/Animation/GameObjectRecorder.bindings.cs","lineNumber":117,"sourceCode":"                throw new ArgumentException(\"FPS can't be 0.0 or less\");\n\n            if (!isRecording)\n                throw new InvalidOperationException(\"Cannot save to clip as there is nothing to save. The method TakeSnapshot() has not been called.\");\n\n            SaveToClipInternal(clip, fps, k_DefaultCurveFilterOptions);\n\n            AnimationUtility.onCurveWasModified?.Invoke(clip, new EditorCurveBinding(), AnimationUtility.CurveModifiedType.ClipModified);\n        }\n\n        public void SaveToClip(AnimationClip clip, float fps, CurveFilterOptions filterOptions)\n        {\n            if (fps <= Mathf.Epsilon)\n                throw new ArgumentException(\"FPS can't be 0.0 or less\");\n\n            if (filterOptions.keyframeReduction)\n            {\n                if (filterOptions.positionError < 0 || filterOptions.rotationError < 0 || filterOptions.scaleError < 0 || filterOptions.floatError < 0)\n                    throw new ArgumentException(\"Allowed errors for keyframe reduction cannot be negative.\");\n            }\n\n            if (!isRecording)\n                throw new InvalidOperationException(\"Cannot save to clip as there is nothing to save. The method TakeSnapshot() has not been called.\");\n\n            SaveToClipInternal(clip, fps, filterOptions);\n\n            AnimationUtility.onCurveWasModified?.Invoke(clip, new EditorCurveBinding(), AnimationUtility.CurveModifiedType.ClipModified);\n        }\n\n        [NativeMethod(\"SaveToClip\")]\n        extern void SaveToClipInternal(AnimationClip clip, float fps, CurveFilterOptions filterOptions);\n\n        extern public void ResetRecording();\n\n        // Obsolete\n        [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]\n        [Obsolete(\"The GameObjectRecorder constructor now takes a root GameObject\", true)]","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/Unity-Technologies/UnityCsReference/blob/225b0fbdb57cc17d094e8056b71f8314aba56f73/Editor/Mono/Animation/GameObjectRecorder.bindings.cs#L99-L135","documentation":"Thrown by the 3-arg GameObjectRecorder.SaveToClip when filterOptions.keyframeReduction is true and any of positionError, rotationError, scaleError, or floatError is negative. Keyframe reduction tolerances are magnitudes; negative values are meaningless and would break the reduction algorithm, so the guard throws ArgumentException before SaveToClipInternal.","triggerScenarios":"Setting CurveFilterOptions errors to -1 to mean 'unset'. Loading filter options from config where fields defaulted to -1. Copying values from a UI that allowed negatives.","commonSituations":"Serialized CurveFilterOptions with sentinel -1 for 'no value'. Editor UI sliders with no lower bound clamp. Tooling that reuses a single options struct and partially resets it.","solutions":["Default all error fields to 0 (or a small positive epsilon) instead of negative sentinels.","Clamp each field: Mathf.Max(0f, value) before passing.","Validate the whole CurveFilterOptions in a helper when keyframeReduction is on.","If reduction is unwanted, set keyframeReduction = false rather than negative errors."],"exampleFix":"// before\nfilterOptions.positionError = -1;\nrecorder.SaveToClip(clip, fps, filterOptions);\n\n// after\nfilterOptions.positionError = Mathf.Max(0f, filterOptions.positionError);\nfilterOptions.rotationError = Mathf.Max(0f, filterOptions.rotationError);\nfilterOptions.scaleError = Mathf.Max(0f, filterOptions.scaleError);\nfilterOptions.floatError = Mathf.Max(0f, filterOptions.floatError);\nrecorder.SaveToClip(clip, fps, filterOptions);","handlingStrategy":"validation","validationCode":"if (filterOptions.keyframeReduction) { filterOptions.positionError = Mathf.Max(0f, filterOptions.positionError); filterOptions.rotationError = Mathf.Max(0f, filterOptions.rotationError); filterOptions.scaleError = Mathf.Max(0f, filterOptions.scaleError); filterOptions.floatError = Mathf.Max(0f, filterOptions.floatError); }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never use negative sentinels for 'unset'; use 0 or disable keyframeReduction.","Clamp all error fields to >= 0 before calling.","Validate the whole CurveFilterOptions in a helper."],"tags":["animation","argument","gameobject-recorder","keyframe-reduction","csharp"],"backgroundTag":null,"analyzedSha":"225b0fbdb57cc17d094e8056b71f8314aba56f73","analyzedAt":"2026-08-13T19:07:19.849Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}