{"record":{"id":"98ebf5f9b66dcc3a","repo":"stride3d/stride","slug":"duration-provided-must-be-greater-than-zero","errorCode":null,"errorMessage":"Duration provided must be greater than zero","messagePattern":"Duration provided must be greater than zero","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.BepuPhysics/Stride.BepuPhysics/BepuSimulation.cs","lineNumber":258,"sourceCode":"    /// Multiplier over <see cref=\"SolverSubStep\"/> during Soft Start\n    /// </summary>\n    [Display(13, \"SoftStart Substep factor\", CategoryConstraints)]\n    public int SoftStartSubstepFactor { get; set; } = 4;\n\n    /// <summary>\n    /// The amount of time between individual simulation steps/ticks, by default ~16.67 milliseconds which would run 60 ticks per second\n    /// </summary>\n    /// <remarks>\n    /// Larger values improve performance at the cost of stability and precision.\n    /// </remarks>\n    [DataMemberIgnore]\n    public TimeSpan FixedTimeStep\n    {\n        get => _fixedTimeStep;\n        set\n        {\n            if (value.Ticks <= 0)\n                throw new ArgumentException(\"Duration provided must be greater than zero\");\n            _fixedTimeStep = value;\n        }\n    }\n\n    #region UglyEditorWorkaroundForMasks\n    // This nonsense is temporary, we need a specific editor UI for this\n    [DefaultValue(CollisionMask.Everything), Display(category:MaskCategory)] public CollisionMask Layer0 { get => CollisionMatrix.Get(CollisionLayer.Layer0); set => CollisionMatrix.Set(CollisionLayer.Layer0, value); }\n    [DefaultValue(CollisionMask.Everything), Display(category:MaskCategory)] public CollisionMask Layer1 { get => CollisionMatrix.Get(CollisionLayer.Layer1); set => CollisionMatrix.Set(CollisionLayer.Layer1, value); }\n    [DefaultValue(CollisionMask.Everything), Display(category:MaskCategory)] public CollisionMask Layer2 { get => CollisionMatrix.Get(CollisionLayer.Layer2); set => CollisionMatrix.Set(CollisionLayer.Layer2, value); }\n    [DefaultValue(CollisionMask.Everything), Display(category:MaskCategory)] public CollisionMask Layer3 { get => CollisionMatrix.Get(CollisionLayer.Layer3); set => CollisionMatrix.Set(CollisionLayer.Layer3, value); }\n    [DefaultValue(CollisionMask.Everything), Display(category:MaskCategory)] public CollisionMask Layer4 { get => CollisionMatrix.Get(CollisionLayer.Layer4); set => CollisionMatrix.Set(CollisionLayer.Layer4, value); }\n    [DefaultValue(CollisionMask.Everything), Display(category:MaskCategory)] public CollisionMask Layer5 { get => CollisionMatrix.Get(CollisionLayer.Layer5); set => CollisionMatrix.Set(CollisionLayer.Layer5, value); }\n    [DefaultValue(CollisionMask.Everything), Display(category:MaskCategory)] public CollisionMask Layer6 { get => CollisionMatrix.Get(CollisionLayer.Layer6); set => CollisionMatrix.Set(CollisionLayer.Layer6, value); }\n    [DefaultValue(CollisionMask.Everything), Display(category:MaskCategory)] public CollisionMask Layer7 { get => CollisionMatrix.Get(CollisionLayer.Layer7); set => CollisionMatrix.Set(CollisionLayer.Layer7, value); }\n    [DefaultValue(CollisionMask.Everything), Display(category:MaskCategory)] public CollisionMask Layer8 { get => CollisionMatrix.Get(CollisionLayer.Layer8); set => CollisionMatrix.Set(CollisionLayer.Layer8, value); }\n    [DefaultValue(CollisionMask.Everything), Display(category:MaskCategory)] public CollisionMask Layer9 { get => CollisionMatrix.Get(CollisionLayer.Layer9); set => CollisionMatrix.Set(CollisionLayer.Layer9, value); }\n    [DefaultValue(CollisionMask.Everything), Display(category:MaskCategory)] public CollisionMask Layer10 { get => CollisionMatrix.Get(CollisionLayer.Layer10); set => CollisionMatrix.Set(CollisionLayer.Layer10, value); }\n    [DefaultValue(CollisionMask.Everything), Display(category:MaskCategory)] public CollisionMask Layer11 { get => CollisionMatrix.Get(CollisionLayer.Layer11); set => CollisionMatrix.Set(CollisionLayer.Layer11, value); }","sourceCodeStart":240,"sourceCodeEnd":276,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.BepuPhysics/Stride.BepuPhysics/BepuSimulation.cs#L240-L276","documentation":"The FixedTimeStep property setter on BepuSimulation validates that the configured physics tick duration is strictly positive (value.Ticks > 0). A zero or negative TimeSpan would cause the simulation loop to spin or divide by zero when computing tick counts, so the setter rejects it with ArgumentException before mutating state.","triggerScenarios":"Assigning BepuSimulation.FixedTimeStep to TimeSpan.Zero, a negative TimeSpan (e.g. TimeSpan.FromSeconds(-0.016)), or an uninitialized TimeSpan field that was never set.","commonSituations":"Config-driven simulation setup where the fixed timestep comes from a settings file that was never filled in, or a default(TimeSpan) field passed through; also typos like TimeSpan.FromSeconds(-1/60).","solutions":["Pass a strictly positive TimeSpan, e.g. sim.FixedTimeStep = TimeSpan.FromSeconds(1.0 / 60.0);","Validate the configured value before assignment: if (ticks <= 0) throw/log before touching the property.","Fix the source of the config value (settings file, YAML/JSON) so it contains a positive duration."],"exampleFix":"// before\nsim.FixedTimeStep = TimeSpan.Zero;\n// after\nsim.FixedTimeStep = TimeSpan.FromSeconds(1.0 / 60.0);","handlingStrategy":"validation","validationCode":"if (timeSpan != null && timeSpan.Ticks > 0) {\n    sim.FixedTimeStep = timeSpan;\n} else {\n    throw new ArgumentException(\"FixedTimeStep must be positive\");\n}","typeGuard":null,"tryCatchPattern":"try { sim.FixedTimeStep = configured; } catch (ArgumentException ex) { log.Error(\"Invalid fixed time step\", ex); sim.FixedTimeStep = TimeSpan.FromSeconds(1.0/60.0); }","preventionTips":["Always initialize timestep from a positive constant like TimeSpan.FromSeconds(1.0/60.0)","Validate config-derived durations immediately after loading","Never use default(TimeSpan) as a timestep"],"tags":["physics","argument","configuration"],"backgroundTag":"invalid-config-value","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}