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
- Match the exact member name and casing from the enum definition (RecognitionTypes, OcrEngineTypes, ImreadModes, TemplateMatchModes, ColorConversionCodes, SearchAnchorMode).
- Check the enum source for the valid members after a rename.
- 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
- Match enum member names exactly (case-sensitive) as defined in code.
- After renaming an enum member, sweep all Recognition.json files for the old value.
- Use a schema/autocomplete in the JSON editor constrained to the real enum members.
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.