babalae/better-genshin-impact · error · NotifierException

Feishu upload image not found image key

Error message

Feishu upload image not found image key

What it means

Thrown by FeishuNotifier.UploadImage after a successful (2xx) HTTP POST to the Feishu image-upload endpoint (https://open.feishu.cn/open-apis/im/v1/images) when the parsed JSON body does not contain a non-empty data.image_key. The library treats a missing/null/empty image_key as a hard failure because the subsequent 'post' message (tag=img) needs that key to reference the uploaded asset.

Source

Thrown at BetterGenshinImpact/Service/Notifier/FeishuNotifier.cs:190

                throw new NotifierException($"Feishu upload image failed with code: {uploadImageResponse.StatusCode}");
            }
            using (JsonDocument doc = JsonDocument.Parse(uploadResponseString))
            {
                JsonElement root = doc.RootElement;
                if (root.TryGetProperty("data", out JsonElement dataElement) &&
                    dataElement.TryGetProperty("image_key", out JsonElement imageKeyElement))
                {
                    var keyNullable = imageKeyElement.GetString();
                    if (keyNullable != null)
                    {
                        imageKey = keyNullable;
                    }
                }
            }
        }
        if (string.IsNullOrEmpty(imageKey))
        {
            throw new NotifierException($"Feishu upload image not found image key");
        }
        return imageKey;
    }
}

View on GitHub (pinned to a7cb36712d)

Solutions

  1. Capture and log uploadResponseString before the throw to see the actual Feishu error code/message (e.g. code 99991663 permission denied).
  2. Confirm the Feishu app has the im:resource (im:message:send_as_image) permission and is published/approved in the developer console.
  3. Verify AppId/AppSecret are correct and that GetAccessToken returns a tenant_access_token for the same app used for upload.
  4. If the response shape changed, harden the parser to read data.code / data.msg and surface them in the exception instead of a generic 'not found image key'.

Example fix

// before
if (string.IsNullOrEmpty(imageKey))
{
    throw new NotifierException($"Feishu upload image not found image key");
}

// after
var code = root.TryGetProperty("code", out var c) ? c.GetInt32() : -1;
var msg = root.TryGetProperty("msg", out var m) ? m.GetString() : uploadResponseString;
if (string.IsNullOrEmpty(imageKey))
{
    throw new NotifierException($"Feishu upload image returned no image_key (code={code}, msg={msg})");
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Before enabling the Feishu image path, sanity-check the app credentials are present.
if (notificationData.Screenshot != null
    && (string.IsNullOrEmpty(notifier.AppId) || string.IsNullOrEmpty(notifier.AppSecret)))
{
    // skip image upload, fall back to text-only — or warn the user.
}

Type guard

// Ensure the credentials look like Feishu app credentials before sending.
static bool HasFeishuAppCredentials(FeishuNotifier n)
    => !string.IsNullOrEmpty(n.AppId) && !string.IsNullOrEmpty(n.AppSecret)
       && n.AppId.StartsWith("cli_");

Try / catch

try { await feishuNotifier.SendAsync(data); }
catch (NotifierException ex) when (ex.Message.Contains("image key"))
{
    // degrade to text-only and retry once
    data.Screenshot = null;
    await feishuNotifier.SendAsync(data);
}

Prevention

When it happens

Trigger: uploadImageResponse.IsSuccessStatusCode is true, JsonDocument.Parse succeeds, but root.TryGetProperty("data", ...) or data.TryGetProperty("image_key", ...) returns false, OR imageKeyElement.GetString() returns null, leaving imageKey empty and triggering the line-188 IsNullOrEmpty guard.

Common situations: Feishu app lacks the im:resource permission scope; the access token is valid but the app is not approved/published so the upload silently returns code!=0 with no data node; the PNG payload exceeds Feishu size limits and the API returns a 200 with an error body; AppId/AppSecret mismatch produces a token with no upload rights; API contract drift after a Feishu OpenAPI version bump.

Related errors


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