babalae/better-genshin-impact · error · ArgumentOutOfRangeException
milliseconds 不能小于 0
Error message
milliseconds 不能小于 0
What it means
Thrown when the Kongying Tavern (空荧酒馆) cloud API endpoint 'api/marker_doc/list_page_bin_md5' returns a JSON envelope with Error=true. The HTTP call itself succeeded (EnsureSuccessStatusCode passed), but the application-level response body indicates a server-side error, carrying the server's Message field. This is a business-logic error distinct from transport failures.
Source
Thrown at BetterGenshinImpact/Core/BgiVision/BvFlow.cs:208
}
public BvFlow WaitUntilDisappear(BvLocator target, int? timeout = null, int? retryInterval = null)
{
ArgumentNullException.ThrowIfNull(target);
return AddWaitStep([target.Clone()], BvFlowCondition.AllDisappear, timeout, retryInterval);
}
public BvFlow WaitUntilAllDisappear(object targets, int? timeout = null, int? retryInterval = null)
{
return AddWaitStep(ParseTargets(targets, nameof(targets)), BvFlowCondition.AllDisappear,
timeout, retryInterval);
}
public BvFlow Wait(int milliseconds)
{
if (milliseconds < 0)
{
throw new ArgumentOutOfRangeException(nameof(milliseconds), "milliseconds 不能小于 0");
}
return AddStep($"Wait({milliseconds})", _ => _services.Delay(milliseconds));
}
public async Task<BvPage> Run()
{
if (Interlocked.CompareExchange(ref _isRunning, 1, 0) != 0)
{
throw new InvalidOperationException("同一个 BvFlow 不能并发执行");
}
try
{
BvFlowStep[] steps;
lock (_syncRoot)
{
_hasStarted = true;View on GitHub (pinned to a7cb36712d)
Solutions
- Check result.Message for the server's specific error text — it often names the root cause (auth, quota, maintenance).
- Force re-authentication by clearing the cached OAuth token so EnsureAccessTokenAsync fetches a fresh one, then retry.
- Verify the server is reachable and not in maintenance by opening https://cloud.yuanshen.site in a browser.
- If the response body is not actually JSON (e.g. an HTML proxy error page), log the raw json string before deserializing to diagnose transport-layer interception.
Example fix
// before
var result = JsonConvert.DeserializeObject<KongyingTavernResponse<List<ListPageBinMd5Item>>>(json);
if (result is null) throw new InvalidOperationException("...");
if (result.Error) throw new InvalidOperationException($"...: {result.Message ?? "未知错误"}");
// after — log raw body and retry once after re-auth
var result = JsonConvert.DeserializeObject<KongyingTavernResponse<List<ListPageBinMd5Item>>>(json);
if (result is null || result.Error)
{
_logger.LogWarning("marker_doc/list_page_bin_md5 异常响应:{RawJson}", json);
await InvalidateAccessTokenAsync(ct);
throw new InvalidOperationException($"marker_doc/list_page_bin_md5 返回错误: {result?.Message ?? "未知错误"}");
} Defensive patterns
Strategy: retry
Validate before calling
// Before calling the marker-doc API, verify token freshness and server reachability
if (await IsAccessTokenExpiredAsync(ct))
{
await InvalidateAccessTokenAsync(ct);
}
var serverOk = await _httpClient.GetAsync(DefaultBaseUrl, ct);
// proceed only if serverOk.IsSuccessStatusCode Try / catch
try
{
return await GetMarkerDocPageMd5ListAsync(ct);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("list_page_bin_md5"))
{
await InvalidateAccessTokenAsync(ct);
return await GetMarkerDocPageMd5ListAsync(ct); // one retry after re-auth
} Prevention
- Proactively refresh the OAuth token before expiry rather than waiting for a server error.
- Log result.Message alongside the raw JSON body to diagnose server-side changes quickly.
- Wrap marker-doc API calls in a retry policy with exponential backoff for transient server errors.
When it happens
Trigger: GetMarkerDocPageMd5ListAsync deserializes the response into KongyingTavernResponse<List<ListPageBinMd5Item>> and checks result.Error. Triggered when the server returns 200 OK with {"error":true,"message":"..."}, e.g. expired access token, invalid marker_doc scope, server maintenance, or upstream database errors.
Common situations: Access token expired or revoked (OAuth token stale), server-side rate limiting, API schema changes after a server update, network proxy returning an HTML error page that deserializes into a default object with Error=true, or the basic-auth credentials changed server-side.
Related errors
- 没有可用的上一步识别位置,无法执行隐式坐标操作
- 无法解析 RecognitionObject 配置文件: {filePath}
- Failed to deserialize macro
- 解析配置组JSON配置失败
- Failed to deserialize JSON.
AI-assisted analysis of babalae/better-genshin-impact@a7cb36712d (2026-08-13).
Data as JSON: /api/errors/be0d97286afbca00.
Report an issue: GitHub.