babalae/better-genshin-impact · error · InvalidOperationException

未知天赋类型:{type}

Error message

未知天赋类型:{type}

What it means

`ApplyTalentResult` switches on the normalized talent type and throws for any value outside {普通攻击, 元素战技, 元素爆发}. Because `ReadTalentDetailWithRetry` only returns types produced by `NormalizeTalentType` (which returns exactly those three or empty), reaching the default branch indicates an internal invariant break.

Source

Thrown at BetterGenshinImpact/GameTask/CharacterDevelopment/CharacterDevelopmentTask.cs:1154

    internal static void ApplyTalentResult(CharacterDevelopmentResult result, string type, int level, bool hasBonus)
    {
        ArgumentNullException.ThrowIfNull(result);
        switch (type)
        {
            case AttackTalentType:
                result.AttackLevel = level;
                result.AttackHasBonus = hasBonus;
                break;
            case SkillTalentType:
                result.SkillLevel = level;
                result.SkillHasBonus = hasBonus;
                break;
            case BurstTalentType:
                result.BurstLevel = level;
                result.BurstHasBonus = hasBonus;
                break;
            default:
                throw new InvalidOperationException($"未知天赋类型:{type}");
        }
    }

    internal static (int Level, int Limit) ParseLevelPair(string text, string fieldName)
    {
        if (!TryParseLevelPair(text, out var level, out var limit))
        {
            throw new InvalidOperationException($"无法从 {fieldName} OCR 结果中解析等级:{text}");
        }

        return (level, limit);
    }

    internal static bool TryParseLevelPair(string text, out int level, out int limit)
    {
        level = 0;
        limit = 0;
        var matches = NumberRegex.Matches(text);

View on GitHub (pinned to a7cb36712d)

Solutions

  1. Only pass `NormalizeTalentType` output into `ApplyTalentResult`.
  2. When adding a talent type constant, update `NormalizeTalentType`, the switch, and the completeness check (error 330) together.
  3. In tests, derive the type from `NormalizeTalentType` rather than hardcoding.

Example fix

// before
ApplyTalentResult(result, "普攻", 8, false); // not a normalized type → throws

// after
var type = NormalizeTalentType(rawTitle); // "普通攻击"
ApplyTalentResult(result, type, level, hasBonus);
Defensive patterns

Strategy: type-guard

Type guard

static bool IsKnownTalentType(string t) =>
    t == "普通攻击" || t == "元素战技" || t == "元素爆发";

Prevention

When it happens

Trigger: `ApplyTalentResult` called directly with an unnormalized/empty type string; `NormalizeTalentType` extended with a new type not added to the switch; a stale type value passed from a test.

Common situations: Unit tests calling `ApplyTalentResult` with arbitrary strings; future talent-type additions that forget to extend the switch.

Related errors


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