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
                    )}
                    """,
                    true

View on GitHub (pinned to f6865c8216)

Solutions

  1. Grant the bot View Channel + Read Message History on the target channel/role.
  2. Re-add the bot to the guild with correct permissions, or have an admin adjust role perms.
  3. For user tokens, confirm the account is still a member of the guild/DM.
  4. 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

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

Related errors


AI-assisted analysis of Tyrrrz/DiscordChatExporter@f6865c8216 (2026-08-13). Data as JSON: /api/errors/ab4c0a11038a0011. Report an issue: GitHub.