Tyrrrz/DiscordChatExporter · error · CommandException
Attempted to export multiple channels, but the output path i
Error message
Attempted to export multiple channels, but the output path is neither a directory nor a template. If the provided output path is meant to be treated as a directory, make sure it ends with a slash. Provided output path: '{OutputPath}'. What it means
Thrown as a CommandException when exporting multiple channels but the resolved output path is neither an existing directory, a path ending in a directory separator, nor a template containing a `%` token. DiscordChatExporter refuses to overwrite a single file with multiple channels' worth of output. The check runs early (before thread fetching) so the user fails fast.
Source
Thrown at DiscordChatExporter.Cli/Commands/Base/ExportCommandBase.cs:192
// https://github.com/Tyrrrz/DiscordChatExporter/issues/1549
var mayExportMultipleChannels =
// Multiple channels were provided explicitly
channels.Count > 1
// Thread inclusion can add more channels to the export
|| ThreadInclusionMode != ThreadInclusionMode.None;
var isValidOutputPath =
// Anything is valid when exporting a single channel
!mayExportMultipleChannels
// When using template tokens, assume the user knows what they're doing
|| OutputPath.Contains('%')
// Otherwise, require an existing directory or an unambiguous directory path
|| Directory.Exists(OutputPath)
|| Path.EndsInDirectorySeparator(OutputPath);
if (!isValidOutputPath)
{
throw new CommandException(
"Attempted to export multiple channels, but the output path is neither a directory nor a template. "
+ "If the provided output path is meant to be treated as a directory, make sure it ends with a slash. "
+ $"Provided output path: '{OutputPath}'."
);
}
var unwrappedChannels = new List<Channel>(channels);
// Unwrap threads
if (ThreadInclusionMode != ThreadInclusionMode.None)
{
await console.Output.WriteLineAsync("Fetching threads...");
var fetchedThreadsCount = 0;
await console
.CreateStatusTicker()
.StartAsync(
"...",View on GitHub (pinned to f6865c8216)
Solutions
- Add a trailing path separator to mark the output as a directory: `-o ./exports/`.
- Use template tokens so each channel gets a distinct file: `-o ./exports/%g-%c.html`.
- Pre-create the directory and pass it (e.g. `mkdir -p exports && -o ./exports`).
- If you really meant a single channel, switch to exportchat with one channel ID.
Example fix
// before dotnet run -- exportall -g <guild> -t <token> -o out.html // after dotnet run -- exportall -g <guild> -t <token> -o "./exports/%g-%c.html"
Defensive patterns
Strategy: validation
Validate before calling
bool isDir = Directory.Exists(options.OutputPath) || Path.EndsInDirectorySeparator(options.OutputPath);
bool isTemplate = options.OutputPath.Contains('%');
bool multiple = channelIds.Count > 1;
if (multiple && !isDir && !isTemplate)
throw new ArgumentException("Output path must be a directory (trailing slash) or a % template for multi-channel export."); Prevention
- Always end multi-channel output paths with a path separator or include a % token.
- Standardize on a template like '%g-%c' for batch exports.
- Pre-create the output directory before running the command.
When it happens
Trigger: Calling exportall/exportguild with more than one resolved channel AND an OutputPath that fails all four conditions in ExportCommandBase.cs:184-189: not a single channel, no `%`, Directory.Exists is false, and Path.EndsInDirectorySeparator is false. Example: `exportall -g <id> -o out.html`.
Common situations: Pointing -o at a filename like `dump.html` when exporting a guild; forgetting the trailing slash on a relative directory; running on a fresh checkout where the target directory has not been created yet.
Related errors
- Option --reuse-media cannot be used without --media.
- Option --media-dir cannot be used without --media.
- Export failed.
- Invalid snowflake '{value}'.
- Invalid partition limit '{value}'.
AI-assisted analysis of Tyrrrz/DiscordChatExporter@f6865c8216 (2026-08-13).
Data as JSON: /api/errors/9b4fdeef82537aae.
Report an issue: GitHub.