{"record":{"id":"13d95b3572338757","repo":"ppy/osu","slug":"hitobjectcontainer-should-be-set-before-handlehit","errorCode":null,"errorMessage":"HitObjectContainer should be set before HandleHit is called.","messagePattern":"HitObjectContainer should be set before HandleHit is called\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"osu.Game.Rulesets.Osu/UI/StartTimeOrderedHitPolicy.cs","lineNumber":60,"sourceCode":"                // 1. The last blocking hitobject has not yet been judged.\r\n                // 2. The current time is before the last hitobject's start time.\r\n                //\r\n                // Hits at exactly the same time as the blocking hitobject are allowed for maps that contain simultaneous hitobjects (e.g. /b/372245).\r\n                if (!blockingObject.Judged && time < blockingObject.HitObject.StartTime)\r\n                    return ClickAction.Shake;\r\n            }\r\n\r\n            // Generally when the user has hit way too early.\r\n            if (result == HitResult.None)\r\n                return ClickAction.Shake;\r\n\r\n            return ClickAction.Hit;\r\n        }\r\n\r\n        public void HandleHit(DrawableHitObject hitObject)\r\n        {\r\n            if (HitObjectContainer == null)\r\n                throw new InvalidOperationException($\"{nameof(HitObjectContainer)} should be set before {nameof(HandleHit)} is called.\");\r\n\r\n            // Hitobjects which themselves don't block future hitobjects don't cause misses (e.g. slider ticks, spinners).\r\n            if (!hitObjectCanBlockFutureHits(hitObject))\r\n                return;\r\n\r\n            if (CheckHittable(hitObject, hitObject.HitObject.StartTime + hitObject.Result.TimeOffset, hitObject.Result.Type) != ClickAction.Hit)\r\n                throw new InvalidOperationException($\"A {hitObject} was hit before it became hittable!\");\r\n\r\n            // Miss all hitobjects prior to the hit one.\r\n            foreach (var obj in enumerateHitObjectsUpTo(hitObject.HitObject.StartTime))\r\n            {\r\n                if (obj.Judged)\r\n                    continue;\r\n\r\n                if (hitObjectCanBlockFutureHits(obj))\r\n                    ((DrawableOsuHitObject)obj).MissForcefully();\r\n            }\r\n        }\r","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/ppy/osu/blob/d9c73e12adff2feaae4a3e158d36fe5883faf6ca/osu.Game.Rulesets.Osu/UI/StartTimeOrderedHitPolicy.cs#L42-L78","documentation":"StartTimeOrderedHitPolicy.HandleHit() requires HitObjectContainer to enumerate and miss all hit objects prior to the hit one. The policy must be initialized with HitObjectContainer before any hit is handled. The null check guards the enumeration inside HandleHit.","triggerScenarios":"Calling HandleHit(hitObject) before setting HitObjectContainer on the StartTimeOrderedHitPolicy instance.","commonSituations":"Same as [13] — policy created without wiring the container; a custom DrawableHitObject that calls HandleHit during load before the playfield finishes setup.","solutions":["Set HitObjectContainer on the policy before any hits can be processed.","Ensure the playfield assigns HitObjectContainer to the policy during LoadComplete, before hit objects become interactive."],"exampleFix":"// before\nvar policy = new StartTimeOrderedHitPolicy();\npolicy.HandleHit(hitObject); // HitObjectContainer is null\n\n// after\nvar policy = new StartTimeOrderedHitPolicy();\npolicy.HitObjectContainer = HitObjectContainer;\npolicy.HandleHit(hitObject);","handlingStrategy":"validation","validationCode":"// Ensure HitObjectContainer is set before any hit can be handled\nif (policy.HitObjectContainer == null)\n    throw new InvalidOperationException(\"HitObjectContainer must be set before gameplay.\");\npolicy.HitObjectContainer = HitObjectContainer;","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Initialize StartTimeOrderedHitPolicy with HitObjectContainer during Playfield.LoadComplete.","Ensure custom DrawableHitObject subclasses do not call HandleHit before the playfield is fully loaded.","Add a test that verifies HandleHit works after proper initialization."],"tags":["osu-ruleset","hit-policy","initialization","gameplay"],"backgroundTag":null,"analyzedSha":"d9c73e12adff2feaae4a3e158d36fe5883faf6ca","analyzedAt":"2026-08-13T14:12:54.015Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}