babalae/better-genshin-impact · error · FormatException

键谱延音符号前没有音符

Error message

键谱延音符号前没有音符

What it means

A FormatException from ParseKeyboardNodes thrown when a '-' (sustain/tie) marker is encountered but the current node list is empty. '-' extends the previous note's Multiplier, so it is illegal at the start of a group or immediately after a group boundary with no preceding note.

Source

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

                index++;
                var expectedClosing = current switch
                {
                    '(' => ')',
                    '[' => ']',
                    '{' => '}',
                    _ => throw new InvalidOperationException()
                };
                node = new KeyboardNode(current, null, ParseKeyboardNodes(text, ref index, expectedClosing));
            }
            else if (current is ')' or ']' or '}')
            {
                throw new FormatException($"键谱出现不匹配的括号:{current}");
            }
            else if (current == '-')
            {
                if (nodes.Count == 0)
                {
                    throw new FormatException("键谱延音符号前没有音符");
                }

                nodes[^1].Multiplier++;
                index++;
                continue;
            }
            else
            {
                node = new KeyboardNode('\0', current, []);
                index++;
            }

            while (index < text.Length && text[index] == '-')
            {
                node.Multiplier++;
                index++;
            }

View on GitHub (pinned to a7cb36712d)

Solutions

  1. Ensure every '-' follows at least one note character within the same bracket scope (e.g. 'Q-' not '-Q').
  2. Remove a stray leading '-' or add the missing note it was meant to extend.
  3. Route through ParseAsync to get an InvalidScore.Error with the message.
  4. Add a pre-parse lint that rejects a score (or group) whose first significant char is '-'.

Example fix

// before
"notes":"-Q"
// after
"notes":"Q-"
Defensive patterns

Strategy: validation

Validate before calling

static bool NoLeadingTie(string s)
{
    // after the same preprocessing the parser applies
    return !Regex.IsMatch(s, @"(^|[(\[{\)\]\}-)-");
}

Type guard

null

Try / catch

var score = await parser.ParseAsync(path, root, ct);
if (!string.IsNullOrEmpty(score.Error)) { Log.Warning(score.Error); continue; }

Prevention

When it happens

Trigger: A keyboard-score string (or a bracketed group) begins with '-', e.g. '-Q', or a group like '(-Q)' where the tie precedes any note inside the group.

Common situations: Typo placing the tie before the note; a converter that emits a leading rest as '-'; copy-paste that dropped the first note but kept its tie.

Related errors


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