mgth/LittleBigMouse · error · FormatException

A delay must follow a KEY_ command.

Error message

A delay must follow a KEY_ command.

What it means

RemoteMacro.Parse tokenizes a macro string: KEY_ commands and integer delay tokens must alternate, with a delay always following a KEY_ command. A leading integer (or one after another delay) has no command to attach the duration to, so FormatException is thrown. Delays are also range-checked to 0–10000 ms.

Solutions

  1. Ensure every macro starts with a KEY_ command and each numeric token immediately follows one (e.g. "KEY_OK 500 KEY_DOWN")
  2. Remove stray leading or duplicated numeric tokens from the macro string
  3. Validate the macro string in the UI before saving/calling Parse
  4. If you need an initial delay, encode it as a command followed by the delay rather than a leading number

Example fix

// before
var macro = RemoteMacro.Parse("500 KEY_OK", ...); // FormatException
// after
var macro = RemoteMacro.Parse("KEY_OK 500", ...);
Defensive patterns

Strategy: try-catch

Validate before calling

static bool IsValidMacro(string s) =>
    !string.IsNullOrWhiteSpace(s) &&
    !int.TryParse(s.Trim().Split(' ', ',')[0], out _); // first token must be a KEY_ command

Type guard

bool StartsWithKeyCommand(string macro) =>
    macro?.TrimStart().StartsWith("KEY_", StringComparison.Ordinal) == true;

Try / catch

try
{
    var macro = RemoteMacro.Parse(input, keyFactory);
}
catch (FormatException ex)
{
    ShowMacroSyntaxError(ex.Message); // "A delay must follow a KEY_ command" / range errors
}

Prevention

When it happens

Trigger: Calling RemoteMacro.Parse with a string whose first token is a bare number (e.g. "500 KEY_OK"), two consecutive delay numbers ("KEY_OK 500 300"), or whitespace-only/number-only input producing an empty command list before the number.

Common situations: Hand-edited macro strings with a stray leading delay; UI macro builder emitting a trailing/leading duration; copy-paste errors; user typing a delay where a KEY_ token was expected; localization stripping the KEY_ prefix.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of mgth/LittleBigMouse@7a42f01d47 (2026-09-16). Data as JSON: /api/errors/deace22d604c440c. Report an issue: GitHub.

Appendix: source

Thrown at LittleBigMouse.Plugins/LittleBigMouse.Plugin.Vcp.Avalonia/RemoteMacro.cs:19

#nullable enable

namespace LittleBigMouse.Plugin.Vcp.Avalonia;

/// <summary>Shared parser for Samsung and VIDAA remote-key macros.</summary>
public static class RemoteMacro
{
    public static IReadOnlyList<(string Key, TimeSpan DelayAfter)> Parse(string sequence)
    {
        var result = new List<(string Key, TimeSpan DelayAfter)>();
        var tokens = sequence.Split(
            [',', ';', '+', '\n', '\r'],
            StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);

        foreach (var token in tokens)
        {
            if (int.TryParse(token, out var milliseconds))
            {
                if (result.Count == 0) throw new FormatException("A delay must follow a KEY_ command.");
                if (milliseconds is < 0 or > 10000)
                    throw new FormatException("Macro delays must be between 0 and 10000 ms.");
                result[^1] = (result[^1].Key, TimeSpan.FromMilliseconds(milliseconds));
                continue;
            }

            var key = token.ToUpperInvariant();
            if (!key.StartsWith("KEY_", StringComparison.Ordinal) || key.Any(char.IsWhiteSpace))
                throw new FormatException($"Invalid remote key: {token}");
            result.Add((key, TimeSpan.FromMilliseconds(150)));
        }

        if (result.Count == 0) throw new FormatException("Enter at least one KEY_ command.");
        return result;
    }
}

View on GitHub (pinned to 7a42f01d47)