{"record":{"id":"000e86b4bad5958e","repo":"ppy/osu","slug":"timed-out-while-loading-beatmap-beatmapinfo","errorCode":null,"errorMessage":"Timed out while loading beatmap ({beatmapInfo}).","messagePattern":"Timed out while loading beatmap \\((.+?)\\)\\.","errorType":"exception","errorClass":"BeatmapLoadTimeoutException","httpStatus":null,"severity":"error","filePath":"osu.Game/Beatmaps/WorkingBeatmap.cs","lineNumber":273,"sourceCode":"        }\r\n\r\n        #endregion\r\n\r\n        #region Playable beatmap\r\n\r\n        public IBeatmap GetPlayableBeatmap(IRulesetInfo ruleset, IReadOnlyList<Mod> mods = null)\r\n        {\r\n            try\r\n            {\r\n                using (var cancellationTokenSource = new CancellationTokenSource(10_000))\r\n                {\r\n                    // don't apply the default timeout when debugger is attached (may be breakpointing / debugging).\r\n                    return GetPlayableBeatmap(ruleset, mods ?? Array.Empty<Mod>(), Debugger.IsAttached ? CancellationToken.None : cancellationTokenSource.Token);\r\n                }\r\n            }\r\n            catch (OperationCanceledException)\r\n            {\r\n                throw new BeatmapLoadTimeoutException(BeatmapInfo);\r\n            }\r\n        }\r\n\r\n        public virtual IBeatmap GetPlayableBeatmap(IRulesetInfo ruleset, IReadOnlyList<Mod> mods, CancellationToken token)\r\n        {\r\n            var rulesetInstance = ruleset.CreateInstance();\r\n\r\n            if (rulesetInstance == null)\r\n                throw new RulesetLoadException(\"Creating ruleset instance failed when attempting to create playable beatmap.\");\r\n\r\n            IBeatmapConverter converter = CreateBeatmapConverter(Beatmap, rulesetInstance);\r\n\r\n            // Check if the beatmap can be converted\r\n            if (Beatmap.HitObjects.Count > 0 && !converter.CanConvert())\r\n                throw new BeatmapInvalidForRulesetException($\"{nameof(Beatmaps.Beatmap)} can not be converted for the ruleset (ruleset: {ruleset.InstantiationInfo}, converter: {converter}).\");\r\n\r\n            // Apply conversion mods\r\n            foreach (var mod in mods.OfType<IApplicableToBeatmapConverter>())\r","sourceCodeStart":255,"sourceCodeEnd":291,"githubUrl":"https://github.com/ppy/osu/blob/d9c73e12adff2feaae4a3e158d36fe5883faf6ca/osu.Game/Beatmaps/WorkingBeatmap.cs#L255-L291","documentation":"Thrown by WorkingBeatmap.GetPlayableBeatmap(ruleset, mods) (the 2-arg overload) when the inner call is cancelled by a 10-second CancellationTokenSource. The catch converts OperationCanceledException into BeatmapLoadTimeoutException(BeatmapInfo), signalling the beatmap could not be decoded/converted within the budget. Note: when Debugger.IsAttached the token is CancellationToken.None, so this never fires while debugging.","triggerScenarios":"Calling GetPlayableBeatmap on a very large, corrupt, or pathological beatmap whose decode + ruleset conversion + mod application exceeds 10s. Also triggered by an unresponsive/slow disk under load, or a ruleset/converter that loops heavily on edge-case data.","commonSituations":"Score simulation/migration over thousands of beatmaps where one stalls; background difficulty calculation; gameplay load on low-end hardware with heavy mod stacks. Disappears under the debugger because the timeout is bypassed — a classic 'works when debugging' symptom.","solutions":["Use the 3-arg overload GetPlayableBeatmap(ruleset, mods, cancellationToken) with your own longer or no cancellation token for batch/offline work.","Investigate the specific beatmap: decode it standalone to find the slow stage (decoder, converter, or a mod) and report/file the offending map.","Ensure disk/realm are healthy and not contended; if running in a tight loop, rate-limit concurrency so a single decode doesn't starve others."],"exampleFix":"// before (10s budget, bypassed under debugger)\nIBeatmap playable = working.GetPlayableBeatmap(rulesetInfo, mods);\n\n// after (caller-controlled budget for offline/batch)\nusing var cts = new CancellationTokenSource(TimeSpan.FromMinutes(1));\nIBeatmap playable = working.GetPlayableBeatmap(rulesetInfo, mods, cts.Token);","handlingStrategy":"try-catch","validationCode":"// For batch/offline work, prefer the token-controlled overload.\nusing var cts = new CancellationTokenSource(TimeSpan.FromMinutes(2));\nIBeatmap playable = working.GetPlayableBeatmap(rulesetInfo, mods, cts.Token);","typeGuard":"static bool CanLoadWithinBudget(WorkingBeatmap wb, IRulesetInfo ruleset, IReadOnlyList<Mod> mods, TimeSpan budget)\n{\n    using var cts = new CancellationTokenSource(budget);\n    try { wb.GetPlayableBeatmap(ruleset, mods, cts.Token); return true; }\n    catch (OperationCanceledException) { return false; }\n}","tryCatchPattern":"try { var playable = working.GetPlayableBeatmap(ruleset, mods); }\ncatch (BeatmapLoadTimeoutException) { /* mark beatmap as problematic, skip or warn user */ }","preventionTips":["Use the 3-arg overload with a caller-controlled token for non-gameplay contexts.","Remember the 2-arg overload is bypassed under the debugger — reproduce timeouts in release.","Profile decode/conversion of pathological beatmaps and file issues for maps that stall."],"tags":["beatmap","performance","timeout","cancellation","gameplay"],"backgroundTag":null,"analyzedSha":"d9c73e12adff2feaae4a3e158d36fe5883faf6ca","analyzedAt":"2026-08-13T14:12:54.015Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}