{"record":{"id":"3735c0b233058147","repo":"ppy/osu","slug":"must-be-joined-to-a-match-to-change-settings","errorCode":null,"errorMessage":"Must be joined to a match to change settings.","messagePattern":"Must be joined to a match to change settings\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"osu.Game/Online/Multiplayer/MultiplayerClient.cs","lineNumber":411,"sourceCode":"\r\n        /// <summary>\r\n        /// Change the current <see cref=\"MultiplayerRoom\"/> settings.\r\n        /// </summary>\r\n        /// <remarks>\r\n        /// A room must be joined for this to have any effect.\r\n        /// </remarks>\r\n        /// <param name=\"name\">The new room name, if any.</param>\r\n        /// <param name=\"password\">The new password, if any.</param>\r\n        /// <param name=\"matchType\">The type of the match, if any.</param>\r\n        /// <param name=\"queueMode\">The new queue mode, if any.</param>\r\n        /// <param name=\"autoStartDuration\">The new auto-start countdown duration, if any.</param>\r\n        /// <param name=\"autoSkip\">The new auto-skip setting.</param>\r\n        /// <param name=\"maxParticipants\">The new participant count limit, if any.</param>\r\n        public Task ChangeSettings(Optional<string> name = default, Optional<string> password = default, Optional<MatchType> matchType = default, Optional<QueueMode> queueMode = default,\r\n                                   Optional<TimeSpan> autoStartDuration = default, Optional<bool> autoSkip = default, Optional<byte?> maxParticipants = default)\r\n        {\r\n            if (Room == null)\r\n                throw new InvalidOperationException(\"Must be joined to a match to change settings.\");\r\n\r\n            return ChangeSettings(new MultiplayerRoomSettings\r\n            {\r\n                Name = name.GetOr(Room.Settings.Name),\r\n                Password = password.GetOr(Room.Settings.Password),\r\n                MatchType = matchType.GetOr(Room.Settings.MatchType),\r\n                QueueMode = queueMode.GetOr(Room.Settings.QueueMode),\r\n                AutoStartDuration = autoStartDuration.GetOr(Room.Settings.AutoStartDuration),\r\n                AutoSkip = autoSkip.GetOr(Room.Settings.AutoSkip),\r\n                MaxParticipants = maxParticipants.GetOr(Room.Settings.MaxParticipants),\r\n            });\r\n        }\r\n\r\n        /// <summary>\r\n        /// Toggles the <see cref=\"LocalUser\"/>'s ready state.\r\n        /// </summary>\r\n        /// <exception cref=\"InvalidOperationException\">If a toggle of ready state is not valid at this time.</exception>\r\n        public async Task ToggleReady()\r","sourceCodeStart":393,"sourceCodeEnd":429,"githubUrl":"https://github.com/ppy/osu/blob/d9c73e12adff2feaae4a3e158d36fe5883faf6ca/osu.Game/Online/Multiplayer/MultiplayerClient.cs#L393-L429","documentation":"Thrown by MultiplayerClient.ChangeSettings when Room is null, meaning the local user is not currently joined to a match. Settings can only be changed against an active joined room.","triggerScenarios":"Calling ChangeSettings(...) before JoinRoom completes, or after the client has been disconnected/parted (Room cleared). The convenience overload builds a MultiplayerRoomSettings from Room.Settings and needs Room to exist.","commonSituations":"Race between leaving a room and a pending settings edit; UI letting the host edit settings after a kick/disconnect; calling ChangeSettings on a client that never joined.","solutions":["Ensure the client is joined (client.Room != null) before invoking ChangeSettings.","Re-acquire the room reference or re-join if Room is null.","Disable settings editing controls when client.Room == null."],"exampleFix":"// before\nawait client.ChangeSettings(name: \"New Name\");\n\n// after\nif (client.Room == null) return;\nawait client.ChangeSettings(name: \"New Name\");","handlingStrategy":"validation","validationCode":"if (client.Room == null) return;\nawait client.ChangeSettings(name: newName);","typeGuard":"bool CanEditSettings(MultiplayerClient c) => c.Room != null;","tryCatchPattern":"try { await client.ChangeSettings(settings); }\ncatch (InvalidOperationException) { /* not joined: ignore or re-prompt join */ }","preventionTips":["Bind settings-edit controls to client.Room != null.","Re-check Room immediately before the call (it can clear on disconnect).","Handle Room-cleared events to disable editing."],"tags":["multiplayer","state-machine","settings","invalid-operation"],"backgroundTag":null,"analyzedSha":"d9c73e12adff2feaae4a3e158d36fe5883faf6ca","analyzedAt":"2026-08-13T14:12:54.015Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}