{"record":{"id":"39870e8ffd8d708f","repo":"babalae/better-genshin-impact","slug":"yuanqin","errorCode":null,"errorMessage":"yuanqin 音符数组中包含非对象元素","messagePattern":"yuanqin 音符数组中包含非对象元素","errorType":"exception","errorClass":"FormatException","httpStatus":null,"severity":"warning","filePath":"BetterGenshinImpact/GameTask/Music/Service/MusicScoreParser.cs","lineNumber":345,"sourceCode":"                    out var denominator))\n            {\n                throw new FormatException($\"无法解析音符 {keys} 的时值：{value}\");\n            }\n\n            tokens.Add(new YuanQinToken(keys, denominator, special));\n        }\n\n        return tokens;\n    }\n\n    private static List<YuanQinToken> ParseYuanQinTokens(JArray notes)\n    {\n        var tokens = new List<YuanQinToken>(notes.Count);\n        foreach (var item in notes)\n        {\n            if (item is not JObject note)\n            {\n                throw new FormatException(\"yuanqin 音符数组中包含非对象元素\");\n            }\n\n            var keys = GetString(note, \"note\", string.Empty);\n            if (string.IsNullOrWhiteSpace(keys))\n            {\n                throw new FormatException(\"yuanqin 音符对象缺少 note 字段\");\n            }\n\n            var special = GetString(note, \"spl\", \"none\");\n            if (special is \"^\" or \"&\")\n            {\n                tokens.Add(new YuanQinToken(keys, 0, special));\n                continue;\n            }\n\n            if (!double.TryParse(\n                    note[\"type\"]?.ToString(),\n                    NumberStyles.Float,","sourceCodeStart":327,"sourceCodeEnd":363,"githubUrl":"https://github.com/babalae/better-genshin-impact/blob/a7cb36712dcb409be610257d877fcea3597e9d6b/BetterGenshinImpact/GameTask/Music/Service/MusicScoreParser.cs#L327-L363","documentation":"Thrown by MusicScoreParser.ParseYuanQinTokens(JArray) when iterating over the notes JSON array and encountering an element that is not a JObject. The yuanqin array form requires each note to be a JSON object with 'note' and optionally 'spl' and 'type' fields. A primitive element (string, number, boolean, null) inside the array triggers this FormatException.","triggerScenarios":"A yuanqin score where 'notes' is a JSON array but contains mixed types — e.g. [{\"note\":\"Q\",\"type\":\"1\"}, \"W\", 42]. Only objects are accepted; the string or number element causes the throw.","commonSituations":"Manual editing of the score JSON inserting a bare string or number instead of an object; a converter tool producing inconsistent array element types.","solutions":["Ensure every element in the notes array is a JSON object with at least a 'note' field (string of keys).","Remove or convert any non-object elements (bare strings, numbers) in the array.","Validate the array schema: each element must be an object like {\"note\":\"Q\", \"type\":\"1\", \"spl\":\"none\"}."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Validate notes array elements are all objects\nif (notes is JArray arr)\n{\n    foreach (var item in arr)\n    {\n        if (item is not JObject)\n            logger.LogError(\"notes 数组包含非对象元素：{Item}\", item);\n    }\n}","typeGuard":"static bool AreAllNotesObjects(JArray notes) => notes.All(i => i is JObject);","tryCatchPattern":"var score = await parser.ParseAsync(path, rootFolder, ct);\nif (!string.IsNullOrEmpty(score.Error)) { logger.LogWarning(score.Error); }","preventionTips":["Ensure every element in the notes array is a JSON object.","Use a JSON schema validator for score files.","Provide a documented example of the notes array schema."],"tags":["music","yuanqin","json","format-exception","user-content"],"backgroundTag":null,"analyzedSha":"a7cb36712dcb409be610257d877fcea3597e9d6b","analyzedAt":"2026-08-13T16:44:57.548Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}