Tyrrrz/DiscordChatExporter · error · DiscordChatExporterException

Failed to export message #{message.Id} in channel '{request.

Error message

Failed to export message #{message.Id} in channel '{request.Channel.Name}' (#{request.Channel.Id}) of guild '{request.Guild.Name} (#{request.Guild.Id})'.

What it means

Thrown as DiscordChatExporterException wrapping the original exception for a single message that failed during the export loop. The message includes channel name/id and guild name/id for context, and sets isFatal by inheriting it from a wrapped DiscordChatExporterException (true if the inner was fatal or was not a DiscordChatExporterException). The inner exception is preserved as InnerException for debugging.

Source

Thrown at DiscordChatExporter.Core/Exporting/ChannelExporter.cs:98

                cancellationToken
            );

        await foreach (var message in messages)
        {
            try
            {
                // Resolve members for referenced users
                foreach (var user in message.GetReferencedUsers())
                    await context.PopulateMemberAsync(user, cancellationToken);

                // Export the message
                if (request.MessageFilter.IsMatch(message))
                    await messageExporter.ExportMessageAsync(message, cancellationToken);
            }
            catch (Exception ex)
            {
                // Provide more context to the exception, to simplify debugging based on error messages
                throw new DiscordChatExporterException(
                    $"Failed to export message #{message.Id} "
                        + $"in channel '{request.Channel.Name}' (#{request.Channel.Id}) "
                        + $"of guild '{request.Guild.Name} (#{request.Guild.Id})'.",
                    ex is not DiscordChatExporterException dex || dex.IsFatal,
                    ex
                );
            }
        }
    }
}

View on GitHub (pinned to f6865c8216)

Solutions

  1. Inspect ex.InnerException for the real cause — the outer message is only context.
  2. For transient IO/network errors, retry the single channel export; assets are re-fetched on demand.
  3. Ensure sufficient disk space and write permissions in the output/assets directory.
  4. If a specific message consistently fails, narrow the --before/--after window to isolate or skip it, and report the inner stack trace upstream.
Defensive patterns

Strategy: try-catch

Validate before calling

// No full prevention; reduce surface by ensuring disk space and asset reachability
if (DriveInfo.GetDiskFreeSpace(outputDir) < 1L * 1024 * 1024 * 1024)
    throw new InvalidOperationException("Insufficient disk space for export.");

Try / catch

try { await exporter.ExportChannelAsync(req, progress, ct); }
catch (DiscordChatExporterException ex) when (ex.Message.StartsWith("Failed to export message"))
{
    logger.LogError(ex.InnerException, "Message failed in {Channel}", req.Channel.Name);
    // optionally continue to next channel without aborting the batch
}

Prevention

When it happens

Trigger: Inside the message enumeration loop, the try block at ChannelExporter.cs resolves referenced members and calls messageExporter.ExportMessageAsync; any thrown exception is caught and re-wrapped at ChannelExporter.cs:99 with the message/guild/channel context.

Common situations: A malformed attachment URL, transient HTTP failure downloading an asset, disk-full/write error, an unparseable embed, or a serialization failure on one message while the rest of the channel exports fine.

Related errors


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