babalae/better-genshin-impact · warning · InvalidOperationException

材料不足以合成指定个数,目标 {targetQuantity},当前最多可合成 {maxQuantity}。

Error message

材料不足以合成指定个数,目标 {targetQuantity},当前最多可合成 {maxQuantity}。

What it means

Thrown by CraftMaterialTask.SetCraftQuantity when the requested targetQuantity exceeds the max craftable quantity read from the crafting UI. The max is obtained via ReadMaxCraftQuantity(), which OCRs the right-hand detail panel. This is a hard precondition guard: the task refuses to drag the slider beyond what the detected materials allow.

Source

Thrown at BetterGenshinImpact/GameTask/Common/Job/CraftMaterialTask.cs:392

    /// 设置本次合成个数并校验最终数量。
    /// </summary>
    /// <param name="targetQuantity">目标合成个数。</param>
    /// <returns>最终校验到的合成个数。</returns>
    /// <exception cref="InvalidOperationException">最大可合成个数、当前合成个数读取失败,材料不足或最终数量不匹配时抛出。</exception>
    private async Task<int> SetCraftQuantity(int targetQuantity)
    {
        var addButton = (X: 1614, Y: 672);
        var reduceButton = (X: 1074, Y: 672);

        var maxQuantity = ReadMaxCraftQuantity();
        if (maxQuantity <= 0)
        {
            throw new InvalidOperationException("未能识别最大可合成个数。");
        }

        if (targetQuantity > maxQuantity)
        {
            throw new InvalidOperationException($"材料不足以合成指定个数,目标 {targetQuantity},当前最多可合成 {maxQuantity}。");
        }

        if (maxQuantity == 1)
        {
            return 1;
        }

        await DragSliderToRatio(0);
        await Delay(250, _ct);

        var ratio = Math.Clamp((targetQuantity - 1d) / (maxQuantity - 1d), 0d, 1d);
        await DragSliderToRatio(ratio);
        await Delay(350, _ct);

        var actualQuantity = ReadCurrentCraftQuantity();
        if (actualQuantity <= 0)
        {
            throw new InvalidOperationException("未能读取当前合成个数。");

View on GitHub (pinned to a7cb36712d)

Solutions

  1. Verify the materials actually exist in-game at the requested quantity before scheduling the craft.
  2. Check that the OCR region Rect1080(1522,653,72,32) still matches the current game layout; re-capture and adjust if a version moved the number.
  3. If the value is genuinely insufficient, lower targetQuantity to <= maxQuantity or gather more materials first.
  4. Add a retry of ReadMaxCraftQuantity before throwing, since a transient OCR miss can understate the max.

Example fix

// before
if (targetQuantity > maxQuantity)
{
    throw new InvalidOperationException($"材料不足以合成指定个数,目标 {targetQuantity},当前最多可合成 {maxQuantity}。");
}

// after: re-read once to absorb transient OCR misses
if (targetQuantity > maxQuantity)
{
    await Delay(300, _ct);
    maxQuantity = ReadMaxCraftQuantity();
}
if (maxQuantity <= 0 || targetQuantity > maxQuantity)
{
    throw new InvalidOperationException($"材料不足以合成指定个数,目标 {targetQuantity},当前最多可合成 {maxQuantity}。");
}
Defensive patterns

Strategy: validation

Validate before calling

// Before calling SetCraftQuantity, cap target to the detected max
var maxQ = ReadMaxCraftQuantity();
var safeTarget = Math.Min(requestedQuantity, maxQ);
if (maxQ <= 0 || safeTarget <= 0)
    throw new InvalidOperationException("无法确定最大可合成个数,拒绝执行合成。");
await SetCraftQuantity(safeTarget);

Type guard

null

Try / catch

null

Prevention

When it happens

Trigger: Caller passes targetQuantity greater than the value returned by ReadMaxCraftQuantity() (OCR of Rect1080(1522,653,72,32) or the material fraction text). Triggered by requesting e.g. 10 crafts when the UI shows max 3, or when OCR under-reads the real max (e.g. reads 3 instead of 30).

Common situations: Recipe config requests more units than the account holds materials for; a game version change shifted the OCR region for the max-quantity number so it reads a smaller value; condensed-resin or material counts were spent between plan time and craft time; UI scaling/resolution misalignment crops the wrong digits.

Related errors


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