paperclipai/paperclip · error · Error
Discord token does not identify a bot user
Error message
Discord token does not identify a bot user
What it means
verifyDiscordBot fetches the authenticated user, application, and guild for a supplied bot token, then sanity-checks the identity. This error means the /users/@me payload did not look like a bot account: user.bot was falsy or id/username were missing — i.e. the token is valid but does not belong to a bot user, or the response was unexpectedly shaped.
Source
Thrown at server/src/services/chat-discord.ts:230
input.botToken,
"/users/@me",
"bot identity lookup",
),
discordJson<DiscordApplication>(
input.fetch,
input.botToken,
"/oauth2/applications/@me",
"application lookup",
),
discordJson<DiscordGuild>(
input.fetch,
input.botToken,
`/guilds/${encodeURIComponent(guildId)}`,
"server membership lookup",
),
]);
if (!user.bot || !user.id || !user.username) {
throw new Error("Discord token does not identify a bot user");
}
if (application.id !== applicationId || user.id !== applicationId) {
throw new Error(
"Discord Application ID does not match the supplied bot token",
);
}
if (((application.flags ?? 0) & MESSAGE_CONTENT_FLAGS) === 0) {
throw new Error(
"Discord Message Content intent is not enabled for this application",
);
}
if (guild.id !== guildId) {
throw new Error("Discord bot is not installed in the selected server");
}
return {
providerAccountId: guildId,
providerAccountLabel: guild.name ?? guildId,
botExternalId: user.id,View on GitHub (pinned to 01ad858492)
Solutions
- Create/copy the token from the Discord Developer Portal under your Application's Bot page (token starting roughly with 'Bot ' semantics) and never a user token or client secret
- Call GET /users/@me manually with the token and confirm the JSON contains "bot": true plus id and username
- Regenerate the bot token if it was reset and update the configured value
Example fix
// before DISCORD_BOT_TOKEN=mFa.abc123.clientsecret // after DISCORD_BOT_TOKEN=MTIzNDU2Nzg5MDEyMzQ1Njc4.GaBcDe.xxxxxxxxxxxxxxxxxxxxxxx
Defensive patterns
Strategy: validation
Validate before calling
// Probe before verifyDiscordBot
const res = await fetch("https://discord.com/api/v10/users/@me", {
headers: { authorization: `Bot ${token}` },
});
const user = await res.json();
if (!res.ok || user.bot !== true || !user.id || !user.username) {
throw new Error("Token is not a valid bot token");
} Type guard
const isBotUser = (u) => !!u && typeof u === "object" && u.bot === true && typeof u.id === "string" && u.id.length > 0 && typeof u.username === "string" && u.username.length > 0;
Try / catch
try {
await verifyDiscordBot(input);
} catch (err) {
if (err.message === "Discord token does not identify a bot user") {
throw new ConfigError("botToken must be a bot token from the Developer Portal, not a user token or client secret");
}
throw err;
} Prevention
- Store only Developer Portal Bot tokens, never user tokens or OAuth client secrets
- Probe GET /users/@me and check bot===true during config onboarding
- Regenerate and re-store tokens after any reset; never commit tokens to the repo
When it happens
Trigger: Using a user account token (not a bot token) as input.botToken; a token that authenticates but returns a user object with bot=false or missing id/username; a Discord API change or proxy stripping fields from the response.
Common situations: Configuring a personal Discord account token instead of a token created under Developer Portal > Bot; copying an OAuth client secret instead of the bot token; partially blocked/undocumented API responses.
Related errors
- Discord Application ID does not match the supplied bot token
- ${options.errorLabel} decision predicate failed: ${detail}
- ${options.errorLabel} decision predicate exited 0 (expected
- PAPERCLIP_BRIDGE_TOKEN is required.
- No auth user has a non-empty credential account, instance-ad
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/de9ea3f91603f8a3.
Report an issue: GitHub.