From 4b2e35ab95f7b06ac917cd86e71b4e24c234b106 Mon Sep 17 00:00:00 2001 From: dhananjai1729 Date: Sat, 28 Feb 2026 15:21:34 +0530 Subject: [PATCH] fix(discord): add token-based fallback for application ID resolution When the Discord API call to /oauth2/applications/@me fails (timeout, network error), the bot fails to start with "Failed to resolve Discord application id". Add a fallback that extracts the application ID by base64-decoding the first segment of the bot token, keeping it as a string to avoid precision loss for snowflake IDs exceeding Number.MAX_SAFE_INTEGER (2^53 - 1). Fixes #29608 Co-Authored-By: Claude Opus 4.6 --- src/discord/probe.ts | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/discord/probe.ts b/src/discord/probe.ts index b199e89fd..d867420f9 100644 --- a/src/discord/probe.ts +++ b/src/discord/probe.ts @@ -165,11 +165,44 @@ export async function probeDiscord( } } +/** + * Extract the application (bot user) ID from a Discord bot token by + * base64-decoding the first segment. Discord tokens have the format: + * base64(user_id) . timestamp . hmac + * The decoded first segment is the numeric snowflake ID as a plain string, + * so we keep it as a string to avoid precision loss for IDs that exceed + * Number.MAX_SAFE_INTEGER. + */ +export function parseApplicationIdFromToken(token: string): string | undefined { + const normalized = normalizeDiscordToken(token); + if (!normalized) { + return undefined; + } + const firstDot = normalized.indexOf("."); + if (firstDot <= 0) { + return undefined; + } + try { + const decoded = Buffer.from(normalized.slice(0, firstDot), "base64").toString("utf-8"); + if (/^\d+$/.test(decoded)) { + return decoded; + } + return undefined; + } catch { + return undefined; + } +} + export async function fetchDiscordApplicationId( token: string, timeoutMs: number, fetcher: typeof fetch = fetch, ): Promise { const json = await fetchDiscordApplicationMe(token, timeoutMs, fetcher); - return json?.id ?? undefined; + if (json?.id) { + return json.id; + } + // Fallback: extract the application ID directly from the token to handle + // cases where the API call fails (timeout, network error, etc.). + return parseApplicationIdFromToken(token); }