ppy/osu · error

Difficulty ""{playableBeatmap.BeatmapInfo.DifficultyName}""

Error message

Difficulty ""{playableBeatmap.BeatmapInfo.DifficultyName}"" has BeatmapID {playableBeatmap.BeatmapInfo.OnlineID} that has not been assigned to it by the server!

What it means

Thrown during beatmap submission when a difficulty's OnlineID is positive (> 0) but is not present in the server-allocated allocatedBeatmapIds list. This signals an inconsistency: the beatmap claims an existing online ID that the server did not allocate for this submission, indicating stale/cached IDs or a set-merge conflict.

Source

Thrown at osu.Game/Screens/Edit/Submission/SubmissionBeatmapExporter.cs:42

        }

        protected override void MutateBeatmap(BeatmapSetInfo beatmapSet, IBeatmap playableBeatmap)
        {
            base.MutateBeatmap(beatmapSet, playableBeatmap);

            if (beatmapSetId != null && allocatedBeatmapIds != null)
            {
                playableBeatmap.BeatmapInfo.BeatmapSet = beatmapSet;
                playableBeatmap.BeatmapInfo.BeatmapSet!.OnlineID = (int)beatmapSetId;

                if (allocatedBeatmapIds.Contains(playableBeatmap.BeatmapInfo.OnlineID))
                {
                    allocatedBeatmapIds.Remove(playableBeatmap.BeatmapInfo.OnlineID);
                    return;
                }

                if (playableBeatmap.BeatmapInfo.OnlineID > 0)
                    throw new InvalidOperationException($@"Difficulty ""{playableBeatmap.BeatmapInfo.DifficultyName}"" has BeatmapID {playableBeatmap.BeatmapInfo.OnlineID} that has not been assigned to it by the server!");

                if (allocatedBeatmapIds.Count == 0)
                    throw new InvalidOperationException(@"Ran out of new beatmap IDs to assign to unsubmitted beatmaps!");

                int newId = allocatedBeatmapIds.First();
                allocatedBeatmapIds.Remove(newId);
                playableBeatmap.BeatmapInfo.OnlineID = newId;
            }
        }
    }
}

View on GitHub (pinned to d9c73e12ad)

Solutions

  1. Clear BeatmapInfo.OnlineID (set to -1 or 0) for difficulties being (re-)submitted so the server allocates fresh IDs.
  2. Verify allocatedBeatmapIds was returned for the correct beatmap set before submission.
  3. If resubmitting, request a fresh allocation from the server rather than reusing cached OnlineIDs.
  4. Audit submission flow to ensure OnlineIDs are only set from server responses.

Example fix

// before
if (playableBeatmap.BeatmapInfo.OnlineID > 0)
    throw new InvalidOperationException(...);

// after (reset before submit)
foreach (var b in beatmapSet.Beatmaps)
    b.OnlineID = -1; // let server allocate
// ... then submit
Defensive patterns

Strategy: validation

Validate before calling

if (beatmap.OnlineID > 0 && !allocatedBeatmapIds.Contains(beatmap.OnlineID))
    beatmap.OnlineID = -1; // reset to let the server allocate

Try / catch

try { exporter.Export(playableBeatmap, beatmapSetId, allocatedBeatmapIds); }
catch (InvalidOperationException) { /* reset IDs and retry */ }

Prevention

When it happens

Trigger: A playable beatmap has BeatmapInfo.OnlineID set to a positive value that is not in allocatedBeatmapIds during submission. The exporter refuses to silently attach an unallocated ID.

Common situations: Re-submitting a beatmap set after a server-side ID reset; merging beatmaps from different sets whose online IDs collide; a previous failed submission left stale OnlineIDs on difficulties.

Related errors


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