Tyrrrz/DiscordChatExporter · info · ChannelEmptyException
Channel '{request.Channel.Name}' of guild '{request.Guild.Na
Error message
Channel '{request.Channel.Name}' of guild '{request.Guild.Name}' does not contain any messages within the specified period; an empty file will be created. What it means
Thrown as ChannelEmptyException when the supplied --before/--after range cannot contain any messages based on channel metadata (e.g. Before predates the channel's earliest possible message, or After postdates its latest). As with [13], MessageExporter is already initialized so an empty file is produced. This is informational.
Source
Thrown at DiscordChatExporter.Core/Exporting/ChannelExporter.cs:60
$"Channel '{request.Channel.Name}' "
+ $"of guild '{request.Guild.Name}' "
+ $"does not contain any messages; an empty file will be created."
);
}
// Check if the 'before' and 'after' boundaries are valid
if (
(
request.Before is not null
&& !request.Channel.MayHaveMessagesBefore(request.Before.Value)
)
|| (
request.After is not null
&& !request.Channel.MayHaveMessagesAfter(request.After.Value)
)
)
{
throw new ChannelEmptyException(
$"Channel '{request.Channel.Name}' "
+ $"of guild '{request.Guild.Name}' "
+ $"does not contain any messages within the specified period; an empty file will be created."
);
}
var messages = !request.IsReverseMessageOrder
? discord.GetMessagesAsync(
request.Channel.Id,
request.After,
request.Before,
progress,
cancellationToken
)
: discord.GetMessagesInReverseAsync(
request.Channel.Id,
request.After,
request.Before,View on GitHub (pinned to f6865c8216)
Solutions
- Widen or correct the --before/--after window so it overlaps the channel's actual message range.
- Drop both bounds to export the entire channel.
- Verify timezone/offset handling when passing ISO timestamps (prefer UTC 'Z' suffix).
- Catch ChannelEmptyException to treat out-of-range channels as non-fatal in batch runs.
Example fix
// before dotnet run -- exportchat -c <id> -t <token> --after 2030-01-01 // after dotnet run -- exportchat -c <id> -t <token> --after 2020-01-01
Defensive patterns
Strategy: validation
Validate before calling
if ((request.Before is not null && !request.Channel.MayHaveMessagesBefore(request.Before.Value))
|| (request.After is not null && !request.Channel.MayHaveMessagesAfter(request.After.Value)))
logger.LogInformation("Date range excludes all messages in {Channel}.", request.Channel.Name); Type guard
static bool DateRangeOverlaps(Channel c, Snowflake? before, Snowflake? after) =>
(before is null || c.MayHaveMessagesBefore(before.Value)) &&
(after is null || c.MayHaveMessagesAfter(after.Value)); Try / catch
try { await exporter.ExportChannelAsync(req, progress, ct); }
catch (ChannelEmptyException ex) when (ex.Message.Contains("specified period"))
{ logger.LogInformation("{Channel} has no messages in range", req.Channel.Name); } Prevention
- Use UTC ISO-8601 timestamps to avoid locale/timezone surprises.
- Validate the window overlaps the channel lifetime before queuing.
- Catch ChannelEmptyException in batches to continue past out-of-range channels.
When it happens
Trigger: ExportChannelAsync reaches the boundary check at ChannelExporter.cs:53-63 when `request.Before` is set and `!request.Channel.MayHaveMessagesBefore(request.Before.Value)`, or `request.After` is set and `!request.Channel.MayHaveMessagesAfter(request.After.Value)`.
Common situations: Exporting a window fully outside the channel's lifetime (Before earlier than channel creation, After later than last message); swapping --before and --after values; timezone mishandling turning a valid window into an impossible one; exporting recent-only on a channel whose last message predates the After cutoff.
Related errors
- Channel '{request.Channel.Name}' of guild '{request.Guild.Na
- Export failed.
- 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/6770d8e306fc9600.
Report an issue: GitHub.