{"record":{"id":"f8434ebe171004fa","repo":"ppy/osu","slug":"not-a-number","errorCode":null,"errorMessage":"Not a number","messagePattern":"Not a number","errorType":"exception","errorClass":"FormatException","httpStatus":null,"severity":"error","filePath":"osu.Game/Beatmaps/Formats/Parsing.cs","lineNumber":25,"sourceCode":"namespace osu.Game.Beatmaps.Formats\r\n{\r\n    /// <summary>\r\n    /// Helper methods to parse from string to number and perform very basic validation.\r\n    /// </summary>\r\n    public static class Parsing\r\n    {\r\n        public const int MAX_COORDINATE_VALUE = 131072;\r\n\r\n        public const double MAX_PARSE_VALUE = int.MaxValue;\r\n\r\n        public static float ParseFloat(string input, float parseLimit = (float)MAX_PARSE_VALUE, bool allowNaN = false)\r\n        {\r\n            float output = float.Parse(input, CultureInfo.InvariantCulture);\r\n\r\n            if (output < -parseLimit) throw new OverflowException(\"Value is too low\");\r\n            if (output > parseLimit) throw new OverflowException(\"Value is too high\");\r\n\r\n            if (!allowNaN && float.IsNaN(output)) throw new FormatException(\"Not a number\");\r\n\r\n            return output;\r\n        }\r\n\r\n        public static double ParseDouble(string input, double parseLimit = MAX_PARSE_VALUE, bool allowNaN = false)\r\n        {\r\n            double output = double.Parse(input, CultureInfo.InvariantCulture);\r\n\r\n            if (output < -parseLimit) throw new OverflowException(\"Value is too low\");\r\n            if (output > parseLimit) throw new OverflowException(\"Value is too high\");\r\n\r\n            if (!allowNaN && double.IsNaN(output)) throw new FormatException(\"Not a number\");\r\n\r\n            return output;\r\n        }\r\n\r\n        public static int ParseInt(string input, int parseLimit = (int)MAX_PARSE_VALUE)\r\n        {\r","sourceCodeStart":7,"sourceCodeEnd":43,"githubUrl":"https://github.com/ppy/osu/blob/d9c73e12adff2feaae4a3e158d36fe5883faf6ca/osu.Game/Beatmaps/Formats/Parsing.cs#L7-L43","documentation":"Thrown by Parsing.ParseFloat when the parsed value is NaN and the allowNaN parameter is false (the default). This fires after the range checks pass, because NaN comparisons always return false. double.Parse/float.Parse will produce NaN if the input string is literally 'NaN'.","triggerScenarios":"Calling Parsing.ParseFloat(input) where input is the string 'NaN' (case-insensitive, since float.Parse accepts it) and allowNaN defaults to false. This commonly occurs when a beatmap field contains the literal text 'NaN' where a number is expected.","commonSituations":"A .osu file where a numeric field (coordinate, timing value, difficulty setting) was set to 'NaN' by a buggy editor or manual edit; a computation that wrote float.NaN.ToString() into the file; corruption during file transfer.","solutions":["Locate the field containing 'NaN' in the .osu/.osb file and replace it with a valid finite number.","If calling ParseFloat directly and NaN is a legitimate sentinel value, pass allowNaN: true.","Sanitize input strings before parsing — replace 'NaN' with '0' or reject the input."],"exampleFix":"// before\nfloat value = Parsing.ParseFloat(input); // throws if input is \"NaN\"\n\n// after (if NaN is legitimate):\nfloat value = Parsing.ParseFloat(input, allowNaN: true);\n\n// after (if NaN is invalid, fix the data):\n// .osu file: replace 'NaN' with a real number like '0'","handlingStrategy":"validation","validationCode":"// Check for NaN before parsing\nif (float.TryParse(input, CultureInfo.InvariantCulture, out float test) && float.IsNaN(test))\n    throw new FormatException($\"Input '{input}' is NaN and NaN is not allowed here\");\nfloat value = Parsing.ParseFloat(input);","typeGuard":null,"tryCatchPattern":"try\n{\n    float value = Parsing.ParseFloat(input);\n}\ncatch (FormatException ex) when (ex.Message == \"Not a number\")\n{\n    Logger.Log($\"Field value '{input}' is NaN — fix the .osu file\", LoggingTarget.Database);\n}","preventionTips":["If NaN is a legitimate sentinel value, pass allowNaN: true to ParseFloat.","Sanitize input strings to replace 'NaN' with a valid default before parsing.","When generating .osu files, never write float.NaN.ToString() — always write finite values."],"tags":["parsing","float","nan","beatmap-decoding","format-error"],"backgroundTag":null,"analyzedSha":"d9c73e12adff2feaae4a3e158d36fe5883faf6ca","analyzedAt":"2026-08-13T14:12:54.015Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}