babalae/better-genshin-impact · warning · FormatException

不支持的 AutoYuanQin 曲谱类型:{type}

Error message

不支持的 AutoYuanQin 曲谱类型:{type}

What it means

Thrown by MusicScoreParser.ParseJsonAsync when the 'type' field in the JSON (lowercased, trimmed) is not one of 'yuanqin', 'midi', or 'keyboard'. The switch expression's default arm throws a FormatException. As with other parse errors, ParseAsync catches this and returns an invalid score.

Source

Thrown at BetterGenshinImpact/GameTask/Music/Service/MusicScoreParser.cs:70

    private static async Task<PerformanceScore> ParseJsonAsync(
        string path,
        string rootFolder,
        CancellationToken cancellationToken)
    {
        var text = await File.ReadAllTextAsync(path, cancellationToken);
        var json = JObject.Parse(text);
        var type = GetString(json, "type", "yuanqin").Trim().ToLowerInvariant();
        var bpm = GetDouble(json, "bpm", 120);
        var ticks = Math.Max(1, (int)Math.Round(GetDouble(json, "ticks", 480)));
        var timeSignature = GetString(json, "time_signature", "4/4");
        var notes = json["notes"] ?? throw new FormatException("曲谱缺少 notes 字段");

        var format = type switch
        {
            "yuanqin" => MusicScoreFormat.YuanQin,
            "midi" => MusicScoreFormat.MidiJson,
            "keyboard" => MusicScoreFormat.Keyboard,
            _ => throw new FormatException($"不支持的 AutoYuanQin 曲谱类型:{type}")
        };

        var timeline = format switch
        {
            MusicScoreFormat.YuanQin => ParseYuanQinTimeline(notes, bpm, timeSignature),
            MusicScoreFormat.MidiJson => ParseMidiJsonTimeline(GetNotesString(notes, format), bpm, ticks),
            MusicScoreFormat.Keyboard => ParseKeyboardTimeline(GetNotesString(notes, format), bpm),
            _ => PerformanceTimeline.Empty
        };

        return new PerformanceScore
        {
            FullPath = path,
            RelativePath = Path.GetRelativePath(rootFolder, path),
            Name = GetString(json, "name", Path.GetFileNameWithoutExtension(path)),
            Author = GetString(json, "author", "未知作者"),
            Instrument = GetString(json, "instrument", "风物之诗琴"),
            Description = GetString(json, "description", "无描述"),

View on GitHub (pinned to a7cb36712d)

Solutions

  1. Set the 'type' field in the JSON to one of: 'yuanqin', 'midi', or 'keyboard'.
  2. Omit the 'type' field entirely to default to 'yuanqin'.
  3. Check the PerformanceScore.Error property returned by ParseAsync for the exact unsupported type value.
  4. If a new format is needed, add a case to the switch and implement the corresponding timeline parser.
Defensive patterns

Strategy: validation

Validate before calling

var supportedTypes = new HashSet<string> { "yuanqin", "midi", "keyboard" };
var type = GetString(json, "type", "yuanqin").Trim().ToLowerInvariant();
if (!supportedTypes.Contains(type))
{
    logger.LogError("不支持的曲谱类型:{Type}", type);
    return;
}

Type guard

static bool IsSupportedScoreType(string type) => type is "yuanqin" or "midi" or "keyboard";

Try / catch

var score = await parser.ParseAsync(path, rootFolder, ct);
if (!string.IsNullOrEmpty(score.Error)) { logger.LogWarning("曲谱解析失败:{Error}", score.Error); }

Prevention

When it happens

Trigger: Loading a .json score file whose 'type' field has a value other than the three supported formats. If 'type' is omitted, it defaults to 'yuanqin' via GetString and does not trigger this error.

Common situations: A score file from an incompatible tool that uses a different type identifier (e.g. 'lyre', 'zither'); a typo in the type field; a future/unrecognized format string.

Related errors


AI-assisted analysis of babalae/better-genshin-impact@a7cb36712d (2026-08-13). Data as JSON: /api/errors/43a1e907dad6af9b. Report an issue: GitHub.