babalae/better-genshin-impact · error · KeyNotFoundException

未找到名称为 {objectName} 的 RecognitionObject 配置

Error message

未找到名称为 {objectName} 的 RecognitionObject 配置

What it means

After the JSON loads, RecognitionObjectJsonLoader.Load looks up the requested objectName in the config.Objects map. If that key is absent it throws KeyNotFoundException, because there is no recognition definition to build. The catch wrapper logs the failure and rethrows.

Source

Thrown at BetterGenshinImpact/Core/Recognition/RecognitionObjectJsonLoader.cs:70

                objectName,
                context.CaptureWidth,
                context.CaptureHeight,
                filePath);
            throw;
        }
    }

    public static RecognitionObject Load(RecognitionObjectJsonFile config, string objectName, RecognitionObjectJsonLoadContext context)
    {
        ArgumentNullException.ThrowIfNull(config);
        ArgumentNullException.ThrowIfNull(objectName);
        ArgumentNullException.ThrowIfNull(context);

        try
        {
            if (!config.Objects.TryGetValue(objectName, out var objectConfig))
            {
                throw new KeyNotFoundException($"未找到名称为 {objectName} 的 RecognitionObject 配置");
            }

            return new Loader(config, context).BuildRecognitionObject(objectName, objectConfig);
        }
        catch (Exception ex)
        {
            Logger.LogError(ex,
                "Recognition 构建失败: {ObjectName} @ {CaptureWidth}x{CaptureHeight}",
                objectName,
                context.CaptureWidth,
                context.CaptureHeight);
            throw;
        }
    }

    private sealed class Loader
    {
        private static readonly string[] RectFunctionNames =

View on GitHub (pinned to a7cb36712d)

Solutions

  1. Add the missing objectName entry to the objects map in Recognition.json.
  2. Correct the objectName string in code so it matches an existing key exactly, including case.
  3. Search the JSON for similar keys to catch typos or renamed identifiers.
  4. Keep object names in a shared constants class to avoid string drift.

Example fix

// before
var ro = RecognitionAssets.Get("AutoFishing", "RodButton"); // key not in objects map

// after
// confirm the key exists in the loaded config first
var config = JsonConvert.DeserializeObject<RecognitionObjectJsonFile>(File.ReadAllText(jsonPath));
if (!config!.Objects.ContainsKey("RodButton"))
    throw new InvalidOperationException("Object 'RodButton' missing from Recognition.json");
var ro = RecognitionAssets.Get("AutoFishing", "RodButton");
Defensive patterns

Strategy: validation

Validate before calling

var json = File.ReadAllText(filePath, Encoding.UTF8);
var config = JsonConvert.DeserializeObject<RecognitionObjectJsonFile>(json)
    ?? throw new InvalidOperationException("Recognition.json is null");
if (!config.Objects.ContainsKey(objectName))
    throw new InvalidOperationException($"Object '{objectName}' not declared in {filePath}");
return RecognitionObjectJsonLoader.LoadFromFile(filePath, objectName, context);

Try / catch

try { return RecognitionObjectJsonLoader.LoadFromFile(filePath, objectName, context); }
catch (KeyNotFoundException ex) when (ex.Message.Contains("的 RecognitionObject 配置"))
{ Logger.LogError(ex, "Object '{Name}' not in {Path}", objectName, filePath); throw; }

Prevention

When it happens

Trigger: Calling Load / RecognitionAssets.Get with an objectName that is not present as a key in the objects map of the task's Recognition.json.

Common situations: Object renamed in JSON but not in calling code (or vice versa); typo in the objectName string; object defined in a different task; copy-paste of a task name without updating object keys.

Related errors


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