Tyrrrz/DiscordChatExporter · error · DiscordChatExporterException
Request to '{url}' failed: forbidden.
Error message
Request to '{url}' failed: forbidden. What it means
Thrown as DiscordChatExporterException (non-fatal) from GetJsonResponseAsync when a request returns 403 Forbidden. The token is valid but the authenticated identity is not permitted to perform the operation or view the resource. The url is interpolated into the message to identify which endpoint was blocked.
Source
Thrown at DiscordChatExporter.Core/Discord/DiscordClient.cs:150
);
private async ValueTask<JsonElement> GetJsonResponseAsync(
string url,
CancellationToken cancellationToken = default
)
{
using var response = await GetResponseAsync(url, cancellationToken);
if (!response.IsSuccessStatusCode)
{
throw response.StatusCode switch
{
HttpStatusCode.Unauthorized => throw new DiscordChatExporterException(
"Authentication token is invalid.",
true
),
HttpStatusCode.Forbidden => throw new DiscordChatExporterException(
$"Request to '{url}' failed: forbidden."
),
HttpStatusCode.NotFound => throw new DiscordChatExporterException(
$"Request to '{url}' failed: not found."
),
_ => throw new DiscordChatExporterException(
$"""
Request to '{url}' failed: {response
.StatusCode.ToString()
.SeparateWords(' ')
.ToLowerInvariant()}.
Response content: {await response.Content.ReadAsStringAsync(
cancellationToken
)}
""",
trueView on GitHub (pinned to f6865c8216)
Solutions
- Grant the bot View Channel + Read Message History on the target channel/role.
- Re-add the bot to the guild with correct permissions, or have an admin adjust role perms.
- For user tokens, confirm the account is still a member of the guild/DM.
- Filter the export list to only channels the identity can access.
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check access by listing channels the identity can see
var channels = await discord.GetGuildChannelsAsync(guildId, ct);
if (!channels.Any(c => c.Id == targetChannelId))
throw new UnauthorizedAccessException("Identity cannot see the target channel."); Try / catch
try { await exporter.ExportChannelAsync(req, progress, ct); }
catch (DiscordChatExporterException ex) when (ex.Message.Contains("forbidden"))
{
logger.LogWarning("Skipping {Channel}: access forbidden", req.Channel.Name);
} Prevention
- Confirm the bot role has View Channel and Read Message History.
- Filter batch lists to channels the identity can access.
- Treat 403 as per-channel skip, not a hard abort.
When it happens
Trigger: Any GetJsonResponseAsync call whose response status is HttpStatusCode.Forbidden. Common cases: requesting messages in a channel the bot cannot read, fetching a guild the user is not in, or an endpoint requiring elevated permissions the bot lacks.
Common situations: Bot added without Read Message History permission; bot lacks View Channel on a private channel; user token querying a guild they left; attempting to read DM channels the account does not have access to; privileged operations without the required OAuth scope.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Authentication token is invalid.
- Request to '{url}' failed: not found.
- Request to '{url}' failed: {response.StatusCode.ToString().S
AI-assisted analysis of Tyrrrz/DiscordChatExporter@f6865c8216 (2026-08-13).
Data as JSON: /api/errors/ab4c0a11038a0011.
Report an issue: GitHub.