ppy/osu · error · InvalidOperationException

Error when exporting {model.GetDisplayString()}: Multiple fi

Error message

Error when exporting {model.GetDisplayString()}: Multiple files specify filename of {file.Filename}

What it means

Thrown by LegacyArchiveExporter during zip export when two files in the model's Files collection share the same Filename. The exporter tracks filenames in a HashSet and refuses to overwrite a duplicate entry inside the zip, which would silently lose data. This typically indicates a data integrity issue in the underlying model.

Source

Thrown at osu.Game/Database/LegacyArchiveExporter.cs:58

        {
            var zipWriterOptions = new ZipWriterOptions(CompressionType.Deflate)
            {
                ArchiveEncoding = UseFixedEncoding ? ZipArchiveReader.DEFAULT_ENCODING : new ArchiveEncoding { Default = Encoding.UTF8, Password = Encoding.UTF8 }
            };

            using (var writer = new ZipWriter(outputStream, zipWriterOptions))
            {
                int i = 0;
                int fileCount = model.Files.Count();
                bool anyFileMissing = false;
                HashSet<string> filesWritten = [];

                foreach (var file in model.Files)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    if (filesWritten.Contains(file.Filename))
                        throw new InvalidOperationException($"Error when exporting {model.GetDisplayString()}: Multiple files specify filename of {file.Filename}");

                    using (var stream = GetFileContents(model, file))
                    {
                        if (stream == null)
                        {
                            Logger.Log($"File {file.Filename} is missing in local storage and will not be included in the export", LoggingTarget.Database);
                            anyFileMissing = true;
                            continue;
                        }

                        writer.Write(file.Filename, stream);
                        filesWritten.Add(file.Filename);
                    }

                    i++;

                    if (notification != null)
                    {

View on GitHub (pinned to d9c73e12ad)

Solutions

  1. Inspect the model's Files collection for duplicate Filenames before exporting.
  2. Deduplicate the Files entries — keep one and remove or rename the others.
  3. If the duplicates are in the realm database, use PerformWrite to fix the model before re-attempting export.
  4. Investigate the root cause of the duplicate creation (import bug, concurrent writes).

Example fix

// before
exporter.Export(model); // throws if model.Files has duplicate filenames

// after
var duplicates = model.Files
    .GroupBy(f => f.Filename)
    .Where(g => g.Count() > 1)
    .ToList();
if (duplicates.Any())
    throw new InvalidOperationException($"Cannot export: duplicate filenames: {string.Join(", ", duplicates.Select(g => g.Key))}");
exporter.Export(model);
Defensive patterns

Strategy: validation

Validate before calling

// Check for duplicate filenames before exporting
var duplicates = model.Files
    .GroupBy(f => f.Filename)
    .Where(g => g.Count() > 1)
    .Select(g => g.Key)
    .ToList();
if (duplicates.Any())
    throw new InvalidOperationException($"Duplicate filenames prevent export: {string.Join(", ", duplicates)}");

Try / catch

try
{
    exporter.Export(model);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("Multiple files specify filename"))
{
    Logger.Log($"Export aborted — duplicate files: {ex.Message}", LoggingTarget.Database);
    // deduplicate or prompt user
}

Prevention

When it happens

Trigger: Calling export on a model (e.g. BeatmapSetInfo or SkinInfo) whose Files collection contains two or more entries with an identical Filename string. The exporter encounters the second occurrence and aborts.

Common situations: A beatmap set with two BeatmapInfo entries whose computed paths point to the same filename (shouldn't happen normally but can result from a bug in filename generation or a corrupted realm database); a skin with duplicate file entries after a botched merge or import; a race condition where a file was added twice.

Related errors


AI-assisted analysis of ppy/osu@d9c73e12ad (2026-08-13). Data as JSON: /api/errors/f9845fb68b07e423. Report an issue: GitHub.