Unity.Services.Lobbies.LobbyServiceException: player is already a member of the lobby

Unity.Services.Lobbies.LobbyServiceException: player is already a member of the lobby —> Unity.Services.Lobbies.Http.HttpException`1[Unity.Services.Lobbies.Models.ErrorStatus]: (409) HTTP/1.1 409 Conflict

I’m new to UGS and been stuck here for a few days.

Here’s my code for authenticate:

private static async Task Authenticate()
    {
        var options = new InitializationOptions();
        options.SetProfile("Player" + Random.Range(0,1000));
       
        await UnityServices.InitializeAsync(options);
        await AuthenticationService.Instance.SignInAnonymouslyAsync();
        Debug.Log(AuthenticationService.Instance.PlayerId);
    }

Here’s my code for creating lobby:

try
        {
            var lobbyOptions = new CreateLobbyOptions
            {
                IsPrivate = true,
                Player = GetPlayer()
            };
            Debug.Log("player " + lobbyOptions.Player.Id);

            Lobby hostLobby = await LobbyService.Instance.CreateLobbyAsync("lobby", 4, lobbyOptions);
            lobbyMenuScript.Initialized_Host(hostLobby);
            PrintPlayers(hostLobby);
        }
        catch (LobbyServiceException e)
        {
            Debug.Log(e);
        }

Here’s my code for joining lobby:

try
        {
            string lobbyCode = joinLobbyInp.text;
            var lobbyOptions = new JoinLobbyByCodeOptions()
            {
                Player = GetPlayer()
            };
            Debug.Log("player " + lobbyOptions.Player.Id);
           
            SetMenuUIsActive(false);
            Lobby joinedLobby = await Lobbies.Instance.JoinLobbyByCodeAsync(lobbyCode, lobbyOptions);
            lobbyMenuScript.Initialized_Joined(joinedLobby);
        }
        catch (LobbyServiceException e)
        {
            Debug.Log(e);
            SetMenuUIsActive(true);
        }

Here’s GetPlayer

    private Player GetPlayer()
    {
        var player = new Player(AuthenticationService.Instance.PlayerId, data: new Dictionary<string, PlayerDataObject>
        {
            {
                "playername", new PlayerDataObject(PlayerDataObject.VisibilityOptions.Member, playerNameInp.text)
            }
        });
       
        return player;
    }

Previously, I’ve been using Parrelsync with setting profiles to it’s clone arguments. The error still happens.
I’ve built it and ran on the same PC, The error still happens.
I’ve built it and ran on another PC, The error still happens.
Now I’m using Multiplayer Play Mode and it still happens.

Can somebody explain what “player” is in the error because I’ve checked AuthenticationService.Instance.PlayerId and they’re not the same when I’m running a virtual instance in Multiplayer Play Mode.

Hi Jescaspim
Thank you for raising this and for providing the code snippets, I was able to reproduce the issue and raised it with the team to look into it, in the meantime, can you try the following:

  • In Multiplayer Playmode, add a new tag to the players - in my code I used “AuthChange”

  • Change your Authenticate method to

using System.Linq;
    private static async Task Authenticate()
    {
#if UNITY_EDITOR
        var mppmTag = CurrentPlayer.ReadOnlyTags();
        if (mppmTag.Contains("AuthChange"))
        {
            var playerProfile = "Player" + UnityEngine.Random.Range(0, 100);
            AuthenticationService.Instance.SwitchProfile(playerProfile);
        }
#endif
        await AuthenticationService.Instance.SignInAnonymouslyAsync();
        Debug.Log("Player ID:" + AuthenticationService.Instance.PlayerId);
    }

Still getting the same error. I don’t know if it’s because I’m using 2023.3.0b4, because the code seem to work on from a year ago tutorials I’ve seen. Also the package versions I’m using are:

  • Lobby 1.1.2
  • Relay 1.0.2
  • Netcode for Gameobjects 1.7.1
  • Multiplayer Tools 2.1.0
  • Multiplayer Play Mode 1.0.0-pre.3

Thank you for the additional details, I will try to replicate the issue and come back to you.
A question that might help, after changing the authenticate code, did you try to deactivate and reactivate the virtual players in Multiplayer Playmode?

The player logic looks fine, I ran something a similar test shown below and it worked for me with the same version of Multiplayer Play Mode.

Few things to be careful around:

  • You can only initialize and process the options once. If you are (or something else is) initializing from anywhere else, options can potentially be ignored.
  • AuthenticationService.Instance.SwitchProfile can be used to avoid that problem prior to Authentication.
  • Make sure each function is only called once. If it’s called again, you will get this error.

I recommend storing and logging/displaying a lot of the information you are tracking to help you debug, like the current Lobby after joining or creating.

Here’s the small test I’ve done in an empty scene:

using System.Threading.Tasks;
using Unity.Services.Authentication;
using Unity.Services.Core;
using Unity.Services.Lobbies;
using Unity.Services.Lobbies.Models;
using UnityEngine;

public class Test : MonoBehaviour
{
    string Profile;
    Lobby Lobby;
    string LobbyCode;

    private void Start()
    {
        Profile = "Player" + Random.Range(0, 1000);
    }

    private void OnGUI()
    {
        GUILayout.Label($"Random Profile: {Profile}");

        if (UnityServices.State != ServicesInitializationState.Initialized)
        {
            if (GUILayout.Button("InitializeAsync"))
            {
                UnityServices.InitializeAsync();
            }

            return;
        }

        GUILayout.Label($"UnityServices.State {UnityServices.State}");

        if (!AuthenticationService.Instance.IsSignedIn)
        {
            if (GUILayout.Button("SignIn"))
            {
                SignInAnonymouslyAsync();
            }

            return;
        }

        GUILayout.Label($"AuthenticationService.Instance.Profile: {AuthenticationService.Instance.Profile}");
        GUILayout.Label($"AuthenticationService.Instance.PlayerId: {AuthenticationService.Instance.PlayerId}");

        if (Lobby == null)
        {
            if (GUILayout.Button("Create Lobby"))
            {
                CreateLobbyAsync();
            }

            using (new GUILayout.HorizontalScope())
            {
                LobbyCode = GUILayout.TextField(LobbyCode);

                if (GUILayout.Button("Join Lobby by Code"))
                {
                    JoinLobbyAsync();
                }
            }
        }
        else
        {
            GUILayout.Label($"LobbyId: {Lobby.Id}");
            GUILayout.Label($"LobbyCode: {Lobby.LobbyCode}");
        }
    }

    public async Task SignInAnonymouslyAsync()
    {
        AuthenticationService.Instance.SwitchProfile(Profile);
        await AuthenticationService.Instance.SignInAnonymouslyAsync();
        Debug.Log(AuthenticationService.Instance.PlayerId);
    }

    public async Task CreateLobbyAsync()
    {
        try
        {
            var lobbyOptions = new CreateLobbyOptions
            {
                IsPrivate = true,
                Player = new Player(AuthenticationService.Instance.PlayerId)
            };

            Debug.Log("player " + lobbyOptions.Player.Id);

            Lobby = await LobbyService.Instance.CreateLobbyAsync("lobby", 4, lobbyOptions);
        }
        catch (LobbyServiceException e)
        {
            Debug.Log(e);
        }
    }

    public async Task JoinLobbyAsync()
    {
        try
        {
            Lobby = await LobbyService.Instance.JoinLobbyByCodeAsync(LobbyCode);
        }
        catch (LobbyServiceException e)
        {
            Debug.Log(e);
        }
    }

    private void OnDestroy()
    {
        if (Lobby != null)
        {
            if (Lobby.HostId == AuthenticationService.Instance.PlayerId)
            {
                LobbyService.Instance.DeleteLobbyAsync(Lobby.Id);
                Debug.Log($"Deleted Lobby.");
            }
            else
            {
                LobbyService.Instance.RemovePlayerAsync(Lobby.Id, AuthenticationService.Instance.PlayerId);
                Debug.Log($"Left Lobby.");
            }
        }
    }
}
1 Like

- Make sure each function is only called once. If it’s called again, you will get this error.

Sorry guys, turns out I’m just dumb! Join was being called twice because I did AddListener and also attached it in the editor. It also didn’t help that the console was collapsing the debugs and I am blind apparently!

I got it working now, thanks guys!

Thanks, I did literally the same thing you did, must be a blindness epidemic.