babalae/better-genshin-impact · error · InvalidOperationException

{fieldName} 的值 {value} 不是有效的 {typeof(TEnum).Name}

Error message

{fieldName} 的值 {value} 不是有效的 {typeof(TEnum).Name}

What it means

ParseEnumExact uses Enum.TryParse with case-sensitivity enabled (the false argument), so the JSON value must exactly match the enum member name. If casing differs or the name is not a member, InvalidOperationException is thrown naming the field, the bad value, and the target enum type.

Source

Thrown at BetterGenshinImpact/Core/Recognition/RecognitionObjectJsonLoader.cs:506

                3 => new Scalar(values[0], values[1], values[2]),
                4 => new Scalar(values[0], values[1], values[2], values[3]),
                _ => throw new InvalidOperationException($"{fieldName} 必须是 1 到 4 个数字"),
            };
        }

        private static TEnum ParseEnumExact<TEnum>(string? value, string fieldName) where TEnum : struct, Enum
        {
            if (string.IsNullOrWhiteSpace(value))
            {
                throw new InvalidOperationException($"{fieldName} 不能为空");
            }

            if (Enum.TryParse<TEnum>(value, false, out var parsed))
            {
                return parsed;
            }

            throw new InvalidOperationException($"{fieldName} 的值 {value} 不是有效的 {typeof(TEnum).Name}");
        }

        private static Color ParseColor(string value)
        {
            return ColorTranslator.FromHtml(value);
        }

        private static double ToDouble(object? value)
        {
            return value switch
            {
                null => 0d,
                byte byteValue => byteValue,
                short shortValue => shortValue,
                int intValue => intValue,
                long longValue => longValue,
                float floatValue => floatValue,
                double doubleValue => doubleValue,

View on GitHub (pinned to a7cb36712d)

Solutions

  1. Match the exact member name and casing from the enum definition (RecognitionTypes, OcrEngineTypes, ImreadModes, TemplateMatchModes, ColorConversionCodes, SearchAnchorMode).
  2. Check the enum source for the valid members after a rename.
  3. Update stale JSON values when an enum member is renamed.

Example fix

// before
// "ocrEngine": "paddleocr"  -> case mismatch -> throws

// after
// "ocrEngine": "PaddleOcr"
Defensive patterns

Strategy: type-guard

Validate before calling

static bool IsValidEnum<TEnum>(string? value) where TEnum : struct, Enum
    => !string.IsNullOrWhiteSpace(value) && Enum.TryParse<TEnum>(value, false, out _);

foreach (var (name, cfg) in config.Objects)
{
    if (!IsValidEnum<RecognitionTypes>(cfg.Type))
        throw new InvalidOperationException($"Object '{name}' type '{cfg.Type}' is not a valid RecognitionTypes member (exact case).");
}

Type guard

static bool IsValidEnumMember<TEnum>(string? value) where TEnum : struct, Enum
    => value is not null && Enum.IsDefined(typeof(TEnum), value);

Try / catch

try { return RecognitionObjectJsonLoader.Load(config, objectName, context); }
catch (InvalidOperationException ex) when (ex.Message.Contains("不是有效的"))
{ Logger.LogError(ex, "Enum field has invalid value/casing."); throw; }

Prevention

When it happens

Trigger: A JSON enum field uses wrong casing or a non-existent member, e.g. "ocrEngine": "paddleocr" instead of "PaddleOcr", or "type": "templatematch" instead of "TemplateMatch".

Common situations: Lowercase or differently-cased value; typo; enum member renamed in code but JSON not updated; copied value from documentation with different casing.

Related errors


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