Players:GetUserIdFromNameAsync() failed: Unknown user

I have a global leaderboard that worked for a few days until suddenly it stopped and I started getting this error:
image

ive searched a lot over the internet, but this seems to be an uncommon error.
this is the script:

[quote=“DevOrange, post:1, topic:2977515, full:true, username:Waffle_Gamer6”]
I have a global leaderboard that worked for a few days until suddenly it stopepd and I started getting this error:
image

ive searched a lot over the internte, but this seems to be an uncommon error.
this is the script:

--// GENERAL VARIABLES
local DSS = game:GetService("DataStoreService")
local DataStore = DSS:GetOrderedDataStore("Wins")

--// UI VARIABLES

local UI = script.Parent.SurfaceGui
local basePlayerFrame = UI.BasePlayerFrame
local boardFrame = UI.ScrollingFrame

--// Functions
local function SaveData()
	for _, player in pairs(game:GetService("Players"):GetPlayers()) do
		local plr_key = "id_"..player.UserId.."_Wins"

		local wins = player.leaderstats.Wins

		local success, result = pcall(function()
			DataStore:SetAsync(plr_key, wins.Value)
		end)

		if not success then 
			warn(result)
		end
	end
end

local function getTop50Players()
	local isAscending = false
	local pageSize = 50
	local pages = DataStore:GetSortedAsync(isAscending, pageSize)
	local top50 = pages:GetCurrentPage()

	local top = {}

	for rank, data in ipairs(top50) do
		local dataName = data.key
		local name = game:GetService("Players"):GetNameFromUserIdAsync(dataName:split('_')[2])
		local wins = data.value

		local currentPlayer =  { Player = name, Wins = wins, Rank = rank, }
		table.insert(top, rank, currentPlayer)
	end

	return top
end

local function ClearList()
	task.spawn(function()	
		for _, plrFrame in pairs(boardFrame:GetChildren()) do
			if not plrFrame:IsA("Frame") then continue end
			plrFrame:Destroy()
			task.wait(0.25)
		end
	end)
end

local function UpdateList()
	SaveData()
	ClearList()
	local top50 = getTop50Players()

	task.spawn(function()	
		for _, plr in ipairs(top50) do
			local frame = basePlayerFrame:Clone()
			frame.Parent = boardFrame

			frame.Plr.Text = plr.Player
			frame.Amount.Text = plr.Wins
			frame.Rank.Text = plr.Rank

			frame.Visible = true
			task.wait(0.25)
		end
	end)
end

task.spawn(function()
	while true do
		UpdateList()
		wait(60)
	end
end)
2 Likes

Print the value of dataName:split('_')[2] to make sure it’s a valid number above 0:

for rank, data in ipairs(top50) do
	local dataName = data.key
    print(dataName:split('_')[2]) -- see what this says
	local name = game:GetService("Players"):GetNameFromUserIdAsync(dataName:split('_')[2])
	local wins = data.value

	local currentPlayer =  { Player = name, Wins = wins, Rank = rank, }
	table.insert(top, rank, currentPlayer)
end
2 Likes

ok so I did that, and it printed out a ton of numbers (player ids I assume) then gave the error for -2

(ignore the stat number found print, thats from another script)

1 Like

-2 is an invalid userid, i assume that’s saved data from a studio playtest you may’ve done. Just add this check to your code to make sure data is only loaded for valid roblox users:

for rank, data in ipairs(top50) do
	local dataName = data.key
    local userId = tonumber(dataName:split('_')[2]) -- it's easier to just have it as its own variable
    if userId < 1 then -- check for valid id
       continue -- skip this person, it's not an actual roblox user 
    end

	local name = game:GetService("Players"):GetNameFromUserIdAsync(userId)
	local wins = data.value

	local currentPlayer =  { Player = name, Wins = wins, Rank = rank, }
	table.insert(top, rank, currentPlayer)
end
3 Likes

that makes a lot of sense, thank you! I did this code and it works but instead of just skipping the “false” player it just stops at where they would be with no errors

1 Like

That’s likely because the invalid user is still part of the top 50 (data wise), so the code doesn’t display them on the leaderboard, but they’re still returned here:

local top50 = pages:GetCurrentPage()

This may be a little complicated, but for this specifically, you’d have to fetch more players (you can likely just get the next page) and add those next users to the list.

(Here’s a poorly made diagram I made in ms paint):

Don’t add all the next users, just enough for the list to reach 50. You can also use DataStoreService:RemoveAsync to remove the invalid users from the DataStore when you find them:

for rank, data in ipairs(top50) do
	local dataName = data.key
    local userId = tonumber(dataName:split('_')[2])
    if userId < 1 then
       pcall(function() -- of course in your actual code base, this would be more detailed
           DataStore:RemoveAsync(dataName) -- remove the invalid user from the data store list
       end)

       continue
    end

	local name = game:GetService("Players"):GetNameFromUserIdAsync(userId)
	local wins = data.value

	local currentPlayer =  { Player = name, Wins = wins, Rank = rank, }
	table.insert(top, rank, currentPlayer)
end

You can add this check to your SaveData function to prevent it from saving studio sessions in the future:

for _, player in pairs(game:GetService("Players"):GetPlayers()) do
    if player.UserId < 1 then
       continue -- don't save this info
    end

	local plr_key = "id_"..player.UserId.."_Wins"
1 Like

thank you! I’m glad my leaderboard works now and that I learned stuff along the way

2 Likes

I dont mean to be annoying here, but my leaderboard broke again in a different way. I made another post for it (although now I realize I shouldve just put it here). here is the link, if you’re able to help thank you! Problem with global leaderboard

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.