{"record":{"id":"a5cf586c55d51d3a","repo":"ppy/osu","slug":"unknown-file-format-line","errorCode":null,"errorMessage":"Unknown file format ({line})","messagePattern":"Unknown file format \\((.+?)\\)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"osu.Game/Beatmaps/Formats/Decoder.cs","lineNumber":84,"sourceCode":"            {\r\n                // consume the previously peeked empty line and advance to the next one\r\n                stream.ReadLine();\r\n                line = stream.PeekLine()?.Trim();\r\n            }\r\n\r\n            if (line == null)\r\n                throw new IOException(\"Unknown file format (no content)\");\r\n\r\n            var decoder = typedDecoders.Where(d => line.StartsWith(d.Key, StringComparison.InvariantCulture)).Select(d => d.Value).FirstOrDefault();\r\n\r\n            // it's important the magic does NOT get consumed here, since sometimes it's part of the structure\r\n            // (see JsonBeatmapDecoder - the magic string is the opening brace)\r\n            // decoder implementations should therefore not die on receiving their own magic\r\n            if (decoder != null)\r\n                return (Decoder<T>)decoder.Invoke(line);\r\n\r\n            if (!fallback_decoders.TryGetValue(typeof(T), out var fallbackDecoder))\r\n                throw new IOException($\"Unknown file format ({line})\");\r\n\r\n            return (Decoder<T>)fallbackDecoder.Invoke();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Registers an instantiation function for a <see cref=\"Decoder\"/>.\r\n        /// </summary>\r\n        /// <param name=\"magic\">A string in the file which triggers this decoder to be used.</param>\r\n        /// <param name=\"constructor\">A function which constructs the <see cref=\"Decoder\"/> given <paramref name=\"magic\"/>.</param>\r\n        protected static void AddDecoder<T>(string magic, Func<string, Decoder> constructor)\r\n        {\r\n            if (!decoders.TryGetValue(typeof(T), out var typedDecoders))\r\n                decoders.Add(typeof(T), typedDecoders = new Dictionary<string, Func<string, Decoder>>());\r\n\r\n            typedDecoders[magic] = constructor;\r\n        }\r\n\r\n        /// <summary>\r","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/ppy/osu/blob/d9c73e12adff2feaae4a3e158d36fe5883faf6ca/osu.Game/Beatmaps/Formats/Decoder.cs#L66-L102","documentation":"Thrown by Decoder.GetDecoder when the first non-empty line of the stream does not match any registered decoder magic string (e.g. 'osu file format v' for LegacyBeatmapDecoder or '{' for JsonBeatmapDecoder), and no fallback decoder is registered for the requested type. The literal first line is included in the message for diagnosis.","triggerScenarios":"Passing a file to GetDecoder whose first content line isn't recognized — e.g. a plain text file, an XML file, a .osu file from an unsupported/very old format version with a different magic, or a file where the magic line is corrupted.","commonSituations":"Feeding a non-beatmap file to the beatmap decoder; a .osu file with a BOM or leading garbage bytes before the magic string; a storyboard file (.osb) that uses an unregistered format; version mismatch where the file uses a format variant not registered in the current build.","solutions":["Inspect the first line of the file (shown in the error message) to confirm it matches an expected magic like 'osu file format vN'.","If the file has a BOM or leading whitespace/garbage, strip it so the magic is at the very start.","Verify that the correct decoder type T is being requested (Beatmap vs Storyboard) — requesting the wrong type will fail to match magic strings.","Ensure decoders are registered (they self-register in the Decoder static constructor, but if the assembly isn't loaded, registration won't happen)."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Peek the first non-empty line to check format before decoding\nstring? firstLine = stream.PeekLine()?.Trim();\nwhile (firstLine != null && firstLine.Length == 0)\n{\n    stream.ReadLine();\n    firstLine = stream.PeekLine()?.Trim();\n}\nif (firstLine == null || (!firstLine.StartsWith(\"osu file format\") && !firstLine.StartsWith(\"{\")))\n    throw new InvalidDataException($\"Unrecognized file format: {firstLine}\");","typeGuard":null,"tryCatchPattern":"try\n{\n    decoder = Decoder.GetDecoder<Beatmap>(reader);\n}\ncatch (IOException ex) when (ex.Message.Contains(\"Unknown file format\"))\n{\n    Logger.Log($\"Unrecognized beatmap format: {ex.Message}\", LoggingTarget.Database);\n}","preventionTips":["Verify the first line of the file starts with the expected magic ('osu file format v' or '{' for JSON).","Strip BOMs or leading garbage bytes from files before decoding.","Request the correct decoder type (Beatmap vs Storyboard) for the file content."],"tags":["decoder","unknown-format","osu-format","io"],"backgroundTag":null,"analyzedSha":"d9c73e12adff2feaae4a3e158d36fe5883faf6ca","analyzedAt":"2026-08-13T14:12:54.015Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}