Unity-Technologies/UnityCsReference · error · ArgumentException

FPS can't be 0.0 or less

Error message

FPS can't be 0.0 or less

What it means

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.

Source

Thrown at Editor/Mono/Animation/GameObjectRecorder.bindings.cs:99

        extern public void BindAll(GameObject target, bool recursive);
        extern public void BindComponent([NotNull] Component component);

        extern public EditorCurveBinding[] GetBindings();

        // Recording.
        extern public void TakeSnapshot(float dt);
        extern public float currentTime { get; }
        extern public bool isRecording { get; }

        public void SaveToClip(AnimationClip clip)
        {
            SaveToClip(clip, 60.0f);
        }

        public void SaveToClip(AnimationClip clip, float fps)
        {
            if (fps <= Mathf.Epsilon)
                throw new ArgumentException("FPS can't be 0.0 or less");

            if (!isRecording)
                throw new InvalidOperationException("Cannot save to clip as there is nothing to save. The method TakeSnapshot() has not been called.");

            SaveToClipInternal(clip, fps, k_DefaultCurveFilterOptions);

            AnimationUtility.onCurveWasModified?.Invoke(clip, new EditorCurveBinding(), AnimationUtility.CurveModifiedType.ClipModified);
        }

        public void SaveToClip(AnimationClip clip, float fps, CurveFilterOptions filterOptions)
        {
            if (fps <= Mathf.Epsilon)
                throw new ArgumentException("FPS can't be 0.0 or less");

            if (filterOptions.keyframeReduction)
            {
                if (filterOptions.positionError < 0 || filterOptions.rotationError < 0 || filterOptions.scaleError < 0 || filterOptions.floatError < 0)
                    throw new ArgumentException("Allowed errors for keyframe reduction cannot be negative.");

View on GitHub (pinned to 225b0fbdb5)

Solutions

  1. Default fps to a sane value (e.g. 30 or 60) when the configured value is <= 0.
  2. Use the parameterless-fps overload SaveToClip(clip) which forwards 60.0f.
  3. Validate fps > Mathf.Epsilon at the config boundary and reject invalid input early.
  4. Clamp fps to a minimum (e.g. Mathf.Max(fps, 1f)) before calling.

Example fix

// before
recorder.SaveToClip(clip, configuredFps);

// after
var fps = configuredFps <= 0 ? 60f : configuredFps;
recorder.SaveToClip(clip, fps);
Defensive patterns

Strategy: validation

Validate before calling

if (fps <= Mathf.Epsilon) fps = 60f;

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of Unity-Technologies/UnityCsReference@225b0fbdb5 (2026-08-13). Data as JSON: /api/errors/0ed12784abcd4074. Report an issue: GitHub.