{"record":{"id":"c9d97b40fc71301d","repo":"ppy/osu","slug":"adjust-via-repeatcount-instead","errorCode":null,"errorMessage":"Adjust via RepeatCount instead","messagePattern":"Adjust via RepeatCount instead","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"osu.Game.Rulesets.Osu/Objects/Slider.cs","lineNumber":34,"sourceCode":"using osu.Game.Audio;\r\nusing osu.Game.Beatmaps;\r\nusing osu.Game.Beatmaps.ControlPoints;\r\nusing osu.Game.Rulesets.Judgements;\r\nusing osu.Game.Rulesets.Objects.Legacy;\r\nusing osu.Game.Rulesets.Osu.Judgements;\r\nusing osu.Game.Rulesets.Scoring;\r\n\r\nnamespace osu.Game.Rulesets.Osu.Objects\r\n{\r\n    public class Slider : OsuHitObject, IHasPathWithRepeats, IHasSliderVelocity, IHasGenerateTicks\r\n    {\r\n        public double EndTime => StartTime + this.SpanCount() * Path.Distance / Velocity;\r\n\r\n        [JsonIgnore]\r\n        public double Duration\r\n        {\r\n            get => EndTime - StartTime;\r\n            set => throw new System.NotSupportedException($\"Adjust via {nameof(RepeatCount)} instead\"); // can be implemented if/when needed.\r\n        }\r\n\r\n        public override IList<HitSampleInfo> AuxiliarySamples => CreateSlidingSamples().Concat(TailSamples).ToArray();\r\n\r\n        private readonly Cached<Vector2> endPositionCache = new Cached<Vector2>();\r\n\r\n        public override Vector2 EndPosition => endPositionCache.IsValid ? endPositionCache.Value : endPositionCache.Value = Position + this.CurvePositionAt(1);\r\n\r\n        public Vector2 StackedPositionAt(double t) => StackedPosition + this.CurvePositionAt(t);\r\n\r\n        private readonly SliderPath path = new SliderPath { OptimiseCatmull = true };\r\n\r\n        public SliderPath Path\r\n        {\r\n            get => path;\r\n            set\r\n            {\r\n                path.ControlPoints.Clear();\r","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/ppy/osu/blob/d9c73e12adff2feaae4a3e158d36fe5883faf6ca/osu.Game.Rulesets.Osu/Objects/Slider.cs#L16-L52","documentation":"Slider.Duration is a computed property derived from EndTime - StartTime, where EndTime depends on SpanCount, Path.Distance, and Velocity. The setter is intentionally disabled with NotSupportedException because setting duration directly would require decomposing it into multiple interdependent factors. The message directs callers to RepeatCount, which adjusts SpanCount and thus the effective duration.","triggerScenarios":"Any code that attempts to assign to Slider.Duration, e.g., slider.Duration = 1000. This includes serialization frameworks that try to round-trip the property, auto-mappers, or ported code from another ruleset where Duration is settable.","commonSituations":"Deserialization frameworks (e.g., JSON.NET) that attempt to set Duration if it appears in serialization; porting hit-object construction logic from a ruleset where Duration is writable; code-generated or reflected property setters.","solutions":["Set RepeatCount instead to adjust the number of spans: slider.RepeatCount = n.","If adjusting velocity, set SliderVelocityMultiplier or the IHasSliderVelocity interface.","If adjusting path length, modify Path control points to change Path.Distance.","If using a serialization framework, add [JsonIgnore] or a custom contract resolver to skip the Duration setter."],"exampleFix":"// before\nslider.Duration = 2000; // throws NotSupportedException\n\n// after — adjust via RepeatCount (each repeat adds one span of Path.Distance / Velocity)\nslider.RepeatCount = 1; // adds one additional span","handlingStrategy":"validation","validationCode":"// Do not assign to Duration — compute RepeatCount from desired duration instead\ndouble desiredDuration = 2000;\ndouble spanDuration = slider.Path.Distance / slider.Velocity;\nint requiredSpans = Math.Max(1, (int)Math.Round(desiredDuration / spanDuration));\nslider.RepeatCount = requiredSpans - 1;","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never assign to Slider.Duration — always adjust RepeatCount, SliderVelocityMultiplier, or Path control points.","If using a serialization framework, ensure Duration has [JsonIgnore] or use a custom contract resolver to prevent the setter from being invoked.","Document the computed nature of Duration in XML docs to prevent misuse."],"tags":["osu-ruleset","hit-objects","api-design","not-supported","slider"],"backgroundTag":null,"analyzedSha":"d9c73e12adff2feaae4a3e158d36fe5883faf6ca","analyzedAt":"2026-08-13T14:12:54.015Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}