babalae/better-genshin-impact · error · NotifierException

Please send a message to the bot first and check that the ch

Error message

Please send a message to the bot first and check that the chat ID is correct.

What it means

User-facing hint thrown when ValidateApiResponse reports the Telegram Bot API returned ok:false with error_code 400. Telegram returns 400 'Bad Request: chat not found' when the chat_id does not exist for the bot — most commonly because the user has never initiated a conversation with the bot (bots cannot message users first under privacy rules) or the chat_id is wrong.

Source

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

    private async Task SendRequestAsync(string endpoint, HttpContent content, string type)
    {
        var request = new HttpRequestMessage(HttpMethod.Post, endpoint) { Content = content };
        request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        request.Headers.UserAgent.Add(new ProductInfoHeaderValue("BetterGenshinImpact", "1.0"));

        var response = await _httpClient.SendAsync(request);
        var responseContent = await response.Content.ReadAsStringAsync();

        if (!response.IsSuccessStatusCode)
            throw new NotifierException($"Telegram {type} message failed: {response.StatusCode}, {responseContent}");

        var (isSuccess, errorCode, errorDescription) = ValidateApiResponse(responseContent);
        if (!isSuccess)
        {
            var msg = errorCode switch
            {
                400 => "Please send a message to the bot first and check that the chat ID is correct.",
                401 => "Telegram bot token is incorrect.",
                404 => $"Telegram API not found (404). Please verify your bot token is correct. URL: {endpoint}",
                _ => $"Telegram API error: {errorDescription} (Code: {errorCode})"
            };
            throw new NotifierException(msg);
        }
    }

    private static string FormatApiBaseUrl(string apiBaseUrl)
    {
        if (string.IsNullOrEmpty(apiBaseUrl)) return DefaultApiUrl;
        var url = apiBaseUrl.Trim();
        if (!url.StartsWith("http://") && !url.StartsWith("https://")) url = "https://" + url;
        if (!url.EndsWith("/")) url += "/";
        if (!url.EndsWith("/bot")) url += "bot";
        return url;
    }

View on GitHub (pinned to a7cb36712d)

Solutions

  1. Open the bot in Telegram and send /start (or any message) so it can reply — required for private chats.
  2. Double-check the chat_id (use getUpdates to read the exact id the bot sees).
  3. For groups, ensure the bot was added as a member and (for privacy-mode groups) that it received a recent message.
  4. If blocked, the user must unblock the bot.
Defensive patterns

Strategy: validation

Validate before calling

// Cannot validate server-side chat existence locally, but can sanity-check the id shape.
if (!long.TryParse(chatId, out _))
    throw new InvalidOperationException("Telegram chat id must be numeric.");

Try / catch

try { await telegramNotifier.SendAsync(data); }
catch (NotifierException ex) when (ex.Message.Contains("send a message to the bot first"))
{ /* instruct user to /start the bot and verify chat_id; no automated retry */ }

Prevention

When it happens

Trigger: SendRequestAsync gets a 200 OK body {"ok":false,"error_code":400,"description":"Bad Request: chat not found"}; ValidateApiResponse returns (false,400,...); the switch maps 400 to this hint.

Common situations: New bot, user never pressed Start / sent any message to it; chat_id typo; messaging a user who blocked the bot; group chat_id used without the bot being a member; chat_id from a different bot.

Related errors


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