ppy/osu · error · InvalidOperationException
Item does not exist in the room.
Error message
Item does not exist in the room.
What it means
RemoveUserPlaylistItem throws when no playlist item matches the given playlistItemId, mirroring the server's removal precondition. The lookup uses FirstOrDefault on ServerRoom.Playlist.
Source
Thrown at osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs:593
item.PlaylistOrder = existingItem.PlaylistOrder;
ServerRoom.Playlist[ServerRoom.Playlist.IndexOf(existingItem)] = item;
ServerAPIRoom.Playlist = ServerAPIRoom.Playlist.Select((pi, i) => pi.ID == item.ID ? new PlaylistItem(item) : ServerAPIRoom.Playlist[i]).ToArray();
await ((IMultiplayerClient)this).PlaylistItemChanged(clone(item)).ConfigureAwait(false);
}
public override Task EditPlaylistItem(MultiplayerPlaylistItem item) => EditUserPlaylistItem(api.LocalUser.Value.OnlineID, clone(item));
public async Task RemoveUserPlaylistItem(int userId, long playlistItemId)
{
Debug.Assert(ServerRoom != null);
Debug.Assert(ServerAPIRoom != null);
var item = ServerRoom.Playlist.FirstOrDefault(i => i.ID == playlistItemId);
if (item == null)
throw new InvalidOperationException("Item does not exist in the room.");
if (item.Equals(currentItem))
throw new InvalidOperationException("The room's current item cannot be removed.");
if (item.OwnerID != userId)
throw new InvalidOperationException("Attempted to remove an item which is not owned by the user.");
if (item.Expired)
throw new InvalidOperationException("Attempted to remove an item which has already been played.");
ServerRoom.Playlist.Remove(item);
ServerAPIRoom.Playlist = ServerAPIRoom.Playlist.Where(i => i.ID != item.ID).ToArray();
await ((IMultiplayerClient)this).PlaylistItemRemoved(clone(playlistItemId)).ConfigureAwait(false);
await updateCurrentItem(ServerRoom).ConfigureAwait(false);
updateRoomStateIfRequired();
}
View on GitHub (pinned to d9c73e12ad)
Solutions
- Pass an ID known to exist in ServerRoom.Playlist.
- Re-query ServerRoom.Playlist for a valid ID before removing.
- Guard against double-removal by checking existence first.
Example fix
// before await client.RemovePlaylistItem(999); // not present // after long id = client.ServerRoom.Playlist.First(i => !i.Expired && i.ID != currentItem?.ID).ID; await client.RemovePlaylistItem(id);
Defensive patterns
Strategy: validation
Validate before calling
if (!ServerRoom.Playlist.Any(i => i.ID == playlistItemId))
throw new InvalidOperationException($"no playlist item {playlistItemId}");
await client.RemovePlaylistItem(playlistItemId); Prevention
- Source removal IDs from ServerRoom.Playlist.
- Guard against double-removal across test steps.
- Re-query the playlist if other users may have removed items.
When it happens
Trigger: Calling RemovePlaylistItem/RemoveUserPlaylistItem with an ID not present in ServerRoom.Playlist.
Common situations: Removing an item twice; removing by a stale or cloned ID; the item was already removed by another user/step.
Related errors
- Attempted to change an item that doesn't exist.
- Attempted to change an item which has already been played.
- The room's current item cannot be removed.
- Attempted to remove an item which has already been played.
- Cannot join an inactive room.
AI-assisted analysis of ppy/osu@d9c73e12ad (2026-08-13).
Data as JSON: /api/errors/6e6c7e4b16ab7441.
Report an issue: GitHub.