babalae/better-genshin-impact · warning · InvalidOperationException

没有可用的上一步识别位置,无法执行隐式坐标操作

Error message

没有可用的上一步识别位置,无法执行隐式坐标操作

What it means

Thrown by ReadLimitedAsync when the cumulative bytes read from a stream exceed MaxDownloadBytes (20 MB) during incremental copy. Unlike the Content-Length pre-check, this guards against chunked-transfer responses or servers that underreport Content-Length — it monitors the actual byte count as data arrives.

Source

Thrown at BetterGenshinImpact/Core/BgiVision/BvFlow.cs:492

            throw new InvalidOperationException("添加流程步骤后不能修改流程默认配置");
        }
    }

    private sealed record BvFlowStep(string Description, Func<BvFlowExecutionContext, Task> Action);

}

internal sealed record BvFlowConditionResult(bool Succeeded, Region? Match);

internal sealed class BvFlowExecutionContext
{
    public Rect? LastMatchRect { get; set; }

    public (double X, double Y) GetLastMatchCenter()
    {
        if (LastMatchRect is not { } rect)
        {
            throw new InvalidOperationException("没有可用的上一步识别位置,无法执行隐式坐标操作");
        }

        return (rect.X + rect.Width / 2d, rect.Y + rect.Height / 2d);
    }
}

internal sealed class BvFlowServices
{
    public required Action ThrowIfCancellationRequested { get; set; }
    public required Func<IReadOnlyList<BvLocator>, BvFlowCondition, BvFlowConditionResult> FindTargets { get; set; }
    public required Func<Region, Rect> GetMatchRect { get; set; }
    public required Func<int, Task> Delay { get; set; }
    public required Func<long> GetTimestamp { get; set; }
    public required Func<long, double> GetElapsedMilliseconds { get; set; }
    public required Action<Vanara.PInvoke.User32.VK> KeyPress { get; set; }
    public required Action<double, double> LeftClick { get; set; }
    public required Action<double, double> RightClick { get; set; }
    public required Action<double, double> MiddleClick { get; set; }

View on GitHub (pinned to a7cb36712d)

Solutions

  1. Use a smaller image source or compress the image.
  2. If legitimate, increase MaxDownloadBytes (recompile required).
  3. Verify the server isn't streaming additional content (e.g. HTML error page) that inflates the body.

Example fix

// before
if (output.Length + read > MaxDownloadBytes)
    throw new InvalidDataException($"图片大小超过 {MaxDownloadBytes / 1024 / 1024} MB 限制。");

// after — stop reading early and return partial/placeholder
if (output.Length + read > MaxDownloadBytes)
{
    _owner.ReportDiagnostic(new MarkdownDiagnostic(MarkdownDiagnosticSeverity.Warning,
        "流式读取时图片大小超过限制,已跳过。"));
    return Array.Empty<byte>(); // caller handles empty as placeholder
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Content-Length pre-check helps, but chunked streams need the runtime guard
// No additional pre-validation possible for chunked streams

Try / catch

try { bytes = await ReadLimitedAsync(responseStream, ct); }
catch (InvalidDataException ex) when (ex.Message.Contains("MB 限制"))
{ return MarkdownImageResult.Placeholder; }

Prevention

When it happens

Trigger: ReadLimitedAsync loops reading into an 81920-byte buffer; when output.Length + read exceeds MaxDownloadBytes it throws. Triggered by HTTP responses without Content-Length (Transfer-Encoding: chunked) where the actual body exceeds 20 MB, or by pack resource streams larger than the limit.

Common situations: Server uses chunked encoding and streams a large image, Content-Length was absent so the pre-check didn't fire, or a pack resource stream is unexpectedly large.

Related errors


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