Pcall error message help!

Hello, I’m having trouble creating a simple leaderboard script for my game.
I’m using Ordered DataStores to get the ranks of the players leaderstats, but i keep getting an error saying

Argument 1 missing or nil - server - Leaderboard:32

It’s from the pcall im using to contain the script, but it still wont work so I need help.

Here is the script: (Script Name: Leaderboard; Type: Script)

local DataStoreService = game:GetService("DataStoreService")
local Key = DataStoreService:GetOrderedDataStore("SaveKey")
local UpdateTime = 10

local function UpdateLeaderboard()
	local succ, err = pcall(function()
		local Data = Key:GetSortedAsync(false, 5)
		local WinsPage = Data:GetCurrentPage()
		for Rank, data in ipairs(WinsPage) do
			local Name = game.Players:GetNameFromUserIdAsync(tonumber(data.key))
			local Amount = data.value
			local IsOnLeaderBoard = false
			for i,v in pairs(game.Workspace.LeaderBoard.Gui.MainHolder:GetChildren()) do
				if v.Player.Text == Name then
					IsOnLeaderBoard = true
					break
				end
			end
			
			if Amount and IsOnLeaderBoard == false then
				local NewFrame = game.ServerStorage:WaitForChild("PlaceHolderFrame"):Clone()
				NewFrame.Player.Text = Name
				NewFrame.Amount.Text = Amount
				NewFrame.Rank = "#"..Rank
				NewFrame.Position = UDim2.new(0,0,NewFrame.Position.Y.Scale + (.08 * #game.Workspace.LeaderBoard.Gui.MainHolder:GetChildren()),0)
				NewFrame.Parent = game.Workspace.LeaderBoard.Gui.MainHolder
			end
		end
	end)
	
	if not succ then
		print(err)
	end
end

while wait(UpdateTime) do
	
	for _,v in pairs(game.Workspace.LeaderBoard.Gui.MainHolder:GetChildren()) do
		v:Destroy()
	end
	
	UpdateLeaderboard()
	print("Leaderboard Updated!")
	
end

Can anyone tell me what is missing or coming up as nil/what is argument 1?
if it helps I have a leaderstats script:

local DataStoreService = game:GetService("DataStoreService")
local Key = DataStoreService:GetOrderedDataStore("SaveKey")

game.Players.PlayerAdded:Connect(function(plr)
	
	local leaderstats = Instance.new("Folder",plr)
	leaderstats.Name = "leaderstats"
	
	local Donations = Instance.new("IntValue",leaderstats)
	Donations.Name = "Donations"
	
	
	local Dons
	
	local succ, err = pcall(function()
		Dons = Key:GetAsync(plr.UserId.."Dons")
	end)	
	if succ then
		plr.leaderstats.Donations.Value = Dons
	else
		warn(err)
	end
	
end)

local SaveData = function(plr)
	local succ, err = pcall(function()
		Key:SetAsync(plr.UserId.."Dons",plr.leaderstats.Donations.Value)
	end)
	if succ then
		print(plr.Name.."'s Donation value is saved!")
	else
		warn(plr.Name.."'s Data was NOT saved!!")
	end
end

game.Players.PlayerRemoving:Connect(function(plr)
	SaveData(plr)
end)

game:GetService("ReplicatedStorage").StatForceSave.leaderstats.Event:Connect(function(plr)
	SaveData(plr)
end)

If you have any idea what argument 1 is that would be very much appreciated! :slight_smile:

Try printing Name since any other function that I see already has potential parameters.

you should wrap ONLY the datastore request with the pcall, or whatever else may error randomly, then needs to be handled by you

also, I agree with above, only Name looks like it may be nil

1 Like

Agreed, wrapping an entire block of code inside pcall is improper.

Dons = Key:GetAsync(plr.UserId.."Dons")

You’re concatenating ‘Dons’ to each datastore key.

tonumber(data.key)

tonumber is therefore going to return nil, you need to remove ‘Dons’ from each key.

local key = string.gsub(data.key, "Dons$", "")
key = tonumber(key)
print(key) --This should output the user's ID.
1 Like

Thank you, It worked however, I am now confused on where the data is saved because when I type:

print(game:GetService("DataStoreService"):GetDataStore("SaveKey"):GetAsync(1072691561))

It doesnt print the correct Amount given to the player when the player joins the game.
same happens with:

game:GetService("DataStoreService"):GetDataStore("SaveKey"):SetAsync("1072691561",6)

This code only changes what printed. but that is what’s the code in the game says.
this is the code inside the game:

Dons = Key:GetAsync(plr.UserId)

I know I’m asking for quite a lot, but could you explain where the data is being saved for this?

the two keys are different because the second one is using a string

Alright but how would I changed the value of the second value say in the command bar?

As others have pointed out, only use pcalls for what you need to, things that may fail, like network calls.

plus, if various network calls, try to wrap them in different pcalls

--NO
pcall(function()
    data:SetAsync
    --If this errors, data2 will fail
    data2:SetAsync
end)

--YES
pcall(function()
    data:Set
end)
pcall(function()
    data2:Set
end)

If you wanted the second call not to be completed if the first one fails do thi, as its proper usage:

local success = pcall(function()
       Data:set
end)

if success then
   pcall(function()
       Data2:set
   end)
end

Keep in mind that pcalls prevent erroring outside, however, if important code is inside the pcall and it errors, you will literally just achieve a similar thing to creating a thread and erroring inside it