babalae/better-genshin-impact · error · ArgumentException

{paramName} 中的每个元素都必须是 {typeof(T).Name}

Error message

{paramName} 中的每个元素都必须是 {typeof(T).Name}

What it means

Inside ParseCollection<T>, after confirming values is enumerable, each element is checked with 'is not T'. If any element is not of the expected type T (e.g. not string), ArgumentException is thrown. This protects the generic helper used by GetByAnyText and similar APIs from silently storing mismatched types that would fail later during OCR matching.

Source

Thrown at BetterGenshinImpact/Core/BgiVision/BvPage.cs:168

    public void Click(double x, double y)
    {
        GameCaptureRegion.GameRegion1080PPosClick(x, y);
    }

    internal static List<T> ParseCollection<T>(object values, string paramName)
    {
        ArgumentNullException.ThrowIfNull(values, paramName);
        if (values is string || values is not IEnumerable enumerable)
        {
            throw new ArgumentException($"{paramName} 必须是集合或 JS Array", paramName);
        }

        List<T> result = [];
        foreach (var value in enumerable)
        {
            if (value is not T typedValue)
            {
                throw new ArgumentException($"{paramName} 中的每个元素都必须是 {typeof(T).Name}", paramName);
            }

            result.Add(typedValue);
        }

        if (result.Count == 0)
        {
            throw new ArgumentException($"{paramName} 不能为空", paramName);
        }

        return result;
    }
}

View on GitHub (pinned to a7cb36712d)

Solutions

  1. Normalize every element to the target type before calling: texts.Select(o => o?.ToString()).
  2. Ensure the source collection is declared with the correct element type.
  3. Validate element types at the interop boundary and coerce or reject early.

Example fix

// before
var loc = page.GetByAnyText(new object[] { "确认", 123 });

// after
var loc = page.GetByAnyText(
    new object[] { "确认", 123 }.Select(o => o.ToString()).ToArray());
Defensive patterns

Strategy: validation

Validate before calling

// coerce heterogeneous interop arrays to the target type
var safe = raw.OfType<object>().Select(o => o?.ToString() ?? string.Empty).ToArray();
var loc = page.GetByAnyText(safe);

Type guard

static bool AllOfType<T>(System.Collections.IEnumerable e) => e.Cast<object>().All(o => o is T);

Prevention

When it happens

Trigger: GetByAnyText(new object[]{ "确认", 123 }) where 123 is not a string; a JS array mixing strings and numbers like ["OK", 5]; passing a List<int> where List<string> is expected.

Common situations: Heterogeneous arrays from untyped interop; config files deserialized into object[]; JS scripts mixing string and numeric literals.

Related errors


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