{"record":{"id":"0ed12784abcd4074","repo":"Unity-Technologies/UnityCsReference","slug":"fps-can-t-be-0-0-or-less","errorCode":null,"errorMessage":"FPS can't be 0.0 or less","messagePattern":"FPS can't be 0\\.0 or less","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"Editor/Mono/Animation/GameObjectRecorder.bindings.cs","lineNumber":99,"sourceCode":"        extern public void BindAll(GameObject target, bool recursive);\n        extern public void BindComponent([NotNull] Component component);\n\n        extern public EditorCurveBinding[] GetBindings();\n\n        // Recording.\n        extern public void TakeSnapshot(float dt);\n        extern public float currentTime { get; }\n        extern public bool isRecording { get; }\n\n        public void SaveToClip(AnimationClip clip)\n        {\n            SaveToClip(clip, 60.0f);\n        }\n\n        public void SaveToClip(AnimationClip clip, float fps)\n        {\n            if (fps <= Mathf.Epsilon)\n                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.\");","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/Unity-Technologies/UnityCsReference/blob/225b0fbdb57cc17d094e8056b71f8314aba56f73/Editor/Mono/Animation/GameObjectRecorder.bindings.cs#L81-L117","documentation":"Thrown by GameObjectRecorder.SaveToClip(AnimationClip clip, float fps) when fps <= Mathf.Epsilon. FPS scales recorded samples to keyframe times; zero or negative FPS would produce NaN/infinite times and divide-by-zero in the native keyframe generation. The default 2-arg overload forwards 60.0f, so this only fires when the caller supplies an explicit non-positive fps.","triggerScenarios":"Calling SaveToClip(clip, 0). Passing an fps read from a config/serialization default that was 0 or uninitialized. Computing fps from a delta-time accumulator that never accumulated (empty recording) and yielded 0.","commonSituations":"Editor tools exposing FPS as a configurable field defaulting to 0. Procedural clip exporters deriving fps from frame counts. Config-driven recorder pipelines with an unset fps value.","solutions":["Default fps to a sane value (e.g. 30 or 60) when the configured value is <= 0.","Use the parameterless-fps overload SaveToClip(clip) which forwards 60.0f.","Validate fps > Mathf.Epsilon at the config boundary and reject invalid input early.","Clamp fps to a minimum (e.g. Mathf.Max(fps, 1f)) before calling."],"exampleFix":"// before\nrecorder.SaveToClip(clip, configuredFps);\n\n// after\nvar fps = configuredFps <= 0 ? 60f : configuredFps;\nrecorder.SaveToClip(clip, fps);","handlingStrategy":"validation","validationCode":"if (fps <= Mathf.Epsilon) fps = 60f;","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Default configurable FPS to 30 or 60, never 0.","Prefer the parameterless-fps overload SaveToClip(clip) when unsure.","Clamp fps to a positive minimum at the config boundary."],"tags":["animation","argument","gameobject-recorder","editor","csharp"],"backgroundTag":null,"analyzedSha":"225b0fbdb57cc17d094e8056b71f8314aba56f73","analyzedAt":"2026-08-13T19:07:19.849Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}