Tyrrrz/DiscordChatExporter · error · DiscordChatExporterException
Channel '{request.Channel.Name}' of guild '{request.Guild.Na
Error message
Channel '{request.Channel.Name}' of guild '{request.Guild.Name}' is a forum and cannot be exported directly. You need to pull its threads and export them individually. What it means
Thrown as DiscordChatExporterException by ChannelExporter.ExportChannelAsync when the target channel's Kind is GuildForum. Forum channels hold no direct messages — only a collection of threads — so exporting them directly would produce nothing. The tool tells the user to export the forum's threads individually instead.
Source
Thrown at DiscordChatExporter.Core/Exporting/ChannelExporter.cs:22
using DiscordChatExporter.Core.Discord;
using DiscordChatExporter.Core.Discord.Data;
using DiscordChatExporter.Core.Exceptions;
using Gress;
namespace DiscordChatExporter.Core.Exporting;
public class ChannelExporter(DiscordClient discord)
{
public async ValueTask ExportChannelAsync(
ExportRequest request,
IProgress<Percentage>? progress = null,
CancellationToken cancellationToken = default
)
{
// Forum channels don't have messages, they are just a list of threads
if (request.Channel.Kind == ChannelKind.GuildForum)
{
throw new DiscordChatExporterException(
$"Channel '{request.Channel.Name}' "
+ $"of guild '{request.Guild.Name}' "
+ $"is a forum and cannot be exported directly. "
+ "You need to pull its threads and export them individually."
);
}
// Build context
var context = new ExportContext(discord, request);
await context.PopulateChannelsAndRolesAsync(cancellationToken);
// Initialize the exporter before further checks to ensure the file is created even if
// an exception is thrown after this point.
await using var messageExporter = new MessageExporter(context);
// Check if the channel is empty
if (request.Channel.IsEmpty)
{View on GitHub (pinned to f6865c8216)
Solutions
- Use exportall/exportguild with --include-threads set to Archived, Unarchived, or All so forum threads are pulled and exported individually.
- List the forum's threads and export each thread ID with exportchat.
- Exclude forum channels from a batch export if you do not want their threads.
Example fix
// before dotnet run -- exportchat -c <forum-channel-id> -t <token> // after dotnet run -- exportall -c <forum-channel-id> -t <token> --include-threads all
Defensive patterns
Strategy: validation
Validate before calling
var channel = await discord.GetChannelAsync(channelId, ct);
if (channel.Kind == ChannelKind.GuildForum)
throw new InvalidOperationException("Use exportall --include-threads to export a forum's threads."); Type guard
static bool IsForum(Channel c) => c.Kind == ChannelKind.GuildForum;
Try / catch
try { await exporter.ExportChannelAsync(req, progress, ct); }
catch (DiscordChatExporterException ex) when (ex.Message.Contains("forum"))
{
logger.LogInformation("{Channel} is a forum — rerun with --include-threads", req.Channel.Name);
} Prevention
- Inspect channel.Kind before calling ExportChannelAsync.
- Use the exportall command with --include-threads for forums.
- Filter forum channels out of direct-export lists.
When it happens
Trigger: ExportChannelAsync is called with a request whose request.Channel.Kind == ChannelKind.GuildForum (ChannelExporter.cs:21). This happens when exportchat is pointed at a forum channel ID.
Common situations: User grabs a forum channel ID and runs exportchat on it; a guild-level exportall flattens forum channels into direct export calls; forum channel reused as a regular channel after a type change.
Related errors
- Export failed.
- Channel '{request.Channel.Name}' of guild '{request.Guild.Na
- Channel '{request.Channel.Name}' of guild '{request.Guild.Na
- Failed to export message #{message.Id} in channel '{request.
AI-assisted analysis of Tyrrrz/DiscordChatExporter@f6865c8216 (2026-08-13).
Data as JSON: /api/errors/d50069be9f5dfa48.
Report an issue: GitHub.