{"record":{"id":"34e5eee933962851","repo":"ppy/osu","slug":"attempted-to-change-an-item-that-doesn-t-exist","errorCode":null,"errorMessage":"Attempted to change an item that doesn't exist.","messagePattern":"Attempted to change an item that doesn't exist\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs","lineNumber":566,"sourceCode":"            await addItem(item).ConfigureAwait(false);\r\n            await updateCurrentItem(ServerRoom).ConfigureAwait(false);\r\n            updateRoomStateIfRequired();\r\n        }\r\n\r\n        public override Task AddPlaylistItem(MultiplayerPlaylistItem item) => AddUserPlaylistItem(api.LocalUser.Value.OnlineID, clone(item));\r\n\r\n        public async Task EditUserPlaylistItem(int userId, MultiplayerPlaylistItem item)\r\n        {\r\n            Debug.Assert(ServerRoom != null);\r\n            Debug.Assert(currentItem != null);\r\n            Debug.Assert(ServerAPIRoom != null);\r\n\r\n            item.OwnerID = userId;\r\n\r\n            var existingItem = ServerRoom.Playlist.SingleOrDefault(i => i.ID == item.ID);\r\n\r\n            if (existingItem == null)\r\n                throw new InvalidOperationException(\"Attempted to change an item that doesn't exist.\");\r\n\r\n            if (existingItem.OwnerID != userId && ServerRoom.Host?.UserID != LocalUser?.UserID)\r\n                throw new InvalidOperationException(\"Attempted to change an item which is not owned by the user.\");\r\n\r\n            if (existingItem.Expired)\r\n                throw new InvalidOperationException(\"Attempted to change an item which has already been played.\");\r\n\r\n            // Ensure the playlist order doesn't change.\r\n            item.PlaylistOrder = existingItem.PlaylistOrder;\r\n\r\n            ServerRoom.Playlist[ServerRoom.Playlist.IndexOf(existingItem)] = item;\r\n            ServerAPIRoom.Playlist = ServerAPIRoom.Playlist.Select((pi, i) => pi.ID == item.ID ? new PlaylistItem(item) : ServerAPIRoom.Playlist[i]).ToArray();\r\n\r\n            await ((IMultiplayerClient)this).PlaylistItemChanged(clone(item)).ConfigureAwait(false);\r\n        }\r\n\r\n        public override Task EditPlaylistItem(MultiplayerPlaylistItem item) => EditUserPlaylistItem(api.LocalUser.Value.OnlineID, clone(item));\r\n\r","sourceCodeStart":548,"sourceCodeEnd":584,"githubUrl":"https://github.com/ppy/osu/blob/d9c73e12adff2feaae4a3e158d36fe5883faf6ca/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs#L548-L584","documentation":"EditUserPlaylistItem looks up the target by item.ID in ServerRoom.Playlist (SingleOrDefault) and throws if nothing matches, reproducing the server's 'item must exist before you can edit it' precondition.","triggerScenarios":"Calling EditPlaylistItem/EditUserPlaylistItem with an ID that is not present in ServerRoom.Playlist (stale, removed, or never-added).","commonSituations":"Editing a cloned item whose ID no longer exists; the item was already removed by another step; using an arbitrary/hardcoded ID.","solutions":["Set item.ID to an existing ServerRoom.Playlist entry's ID before editing.","Re-read the current playlist from ServerRoom.Playlist to get a valid ID.","If the item should not exist yet, AddPlaylistItem it first instead of editing."],"exampleFix":"// before\nitem.ID = 999; // not in playlist\nawait client.EditPlaylistItem(item);\n\n// after\nitem.ID = client.ServerRoom.Playlist.First(i => !i.Expired).ID;\nawait client.EditPlaylistItem(item);","handlingStrategy":"validation","validationCode":"var existing = ServerRoom.Playlist.SingleOrDefault(i => i.ID == item.ID);\nif (existing == null)\n    throw new InvalidOperationException($\"no playlist item {item.ID} to edit\");\nawait client.EditPlaylistItem(item);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always source the ID from ServerRoom.Playlist, never a literal.","Re-query the playlist before editing if other steps may have mutated it.","Prefer Add for new items rather than editing a non-existent ID."],"tags":["test-infra","multiplayer","playlist","validation"],"backgroundTag":null,"analyzedSha":"d9c73e12adff2feaae4a3e158d36fe5883faf6ca","analyzedAt":"2026-08-13T14:12:54.015Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}