babalae/better-genshin-impact · error · KeyNotFoundException
未找到区域别名 {alias}
Error message
未找到区域别名 {alias} What it means
A region (ROI) expression may start with '@' to reference a named alias from the JSON regions map. ResolveRegionExpression dereferences it and throws KeyNotFoundException when the alias is undefined, so the rectangle cannot be resolved.
Source
Thrown at BetterGenshinImpact/Core/Recognition/RecognitionObjectJsonLoader.cs:339
{
var resolved = ResolveRegionExpression(expression);
var value = EvaluateValue(resolved);
return value switch
{
Rect rect => rect,
_ => throw new InvalidOperationException($"表达式 {expression} 未返回 Rect")
};
}
private string ResolveRegionExpression(string expression)
{
var resolved = expression.Trim();
while (resolved.StartsWith('@'))
{
var alias = resolved[1..];
if (!_config.Regions.TryGetValue(alias, out resolved))
{
throw new KeyNotFoundException($"未找到区域别名 {alias}");
}
}
return resolved;
}
private object EvaluateValue(string expression, string? skipVarName = null)
{
var normalizedExpression = NormalizeExpression(expression);
var ncalcExpression = new Expression(normalizedExpression);
foreach (var (name, value) in BuildParameters(skipVarName))
{
ncalcExpression.Parameters[name] = value;
}
ncalcExpression.Functions["rect"] = args => BuildRect(args.Evaluate(0), args.Evaluate(1), args.Evaluate(2), args.Evaluate(3));
ncalcExpression.Functions["cutLeft"] = args => _captureRect.CutLeft(ToDouble(args.Evaluate(0)));View on GitHub (pinned to a7cb36712d)
Solutions
- Declare the region alias in the regions map, e.g. "regions": { "topBar": "rect(0,0,cw,40)" }.
- Inline the rect expression directly in roi if the alias is not needed.
- Check alias spelling and case against the regions map keys.
Example fix
// before
// "roi": "@topBar" with no regions.topBar -> throws
// after
// "regions": { "topBar": "rect(0, 0, cw, 40)" },
// "objects": { "x": { "roi": "@topBar" } } Defensive patterns
Strategy: validation
Validate before calling
foreach (var (name, cfg) in config.Objects)
{
if (cfg.Roi is { } r && r.TrimStart().StartsWith('@'))
{
var alias = r.Trim()[1..];
if (!config.Regions.ContainsKey(alias))
throw new InvalidOperationException($"Object '{name}' references undefined region alias '@{alias}'.");
}
} Try / catch
try { return RecognitionObjectJsonLoader.Load(config, objectName, context); }
catch (KeyNotFoundException ex) when (ex.Message.Contains("未找到区域别名"))
{ Logger.LogError(ex, "Undefined region alias referenced."); throw; } Prevention
- Keep the regions map and '@' ROI references consistent.
- Lint all '@'-prefixed references (templates and regions) during CI.
- Inline rect expressions for one-off regions to avoid alias drift.
When it happens
Trigger: An object has "roi": "@topBar" but the Recognition.json defines no regions.topBar entry.
Common situations: Region alias removed/renamed but still referenced; typo in the alias; alias defined in a shared file not loaded.
Related errors
AI-assisted analysis of babalae/better-genshin-impact@a7cb36712d (2026-08-13).
Data as JSON: /api/errors/132719c947fe15ff.
Report an issue: GitHub.