Unable to cast to array

Hello, I followed @GEILER123456’s tutorial on how to make a datastore, but the error keep printing out “There was an error with saving a player’s data Unable to cast to array”. What does this error mean, and how could it be fixed?
Here is the script:

local dataStoreService = game:GetService("DataStoreService")
local players = game:GetService("Players")

local dataStore = dataStoreService:GetDataStore("Name")

local function leaderboardSetUp(player)
	local userId = player.UserId
	local key = "Player_" .. userId
	local data = dataStore:GetAsync(key)
	
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player
	
	local wins = Instance.new("IntValue")
	wins.Name = "Wins"
	wins.Value = data or 0
	wins.Parent = leaderstats
	
	local money = Instance.new("IntValue")
	money.Name = "Money"
	money.Value = data or 0
	money.Parent = leaderstats

	print("Leaderstats loaded.")

end

local function save(player)
	local userId = player.UserId
	local key = "Player_" .. userId
	local leaderstats = player:FindFirstChild("leaderstats")

	if leaderstats then
		local winsValue = leaderstats.Wins.Value
		local moneyValue = leaderstats.Money.Value
		local success, ret = pcall(dataStore.GetAsync, dataStore, key, winsValue, moneyValue)

		if success then
			print("Data has been saved successfully!")
		else
			print("There was an error with saving a player's data" .. ret)
		end
	end
end

local function onShutDown()
	wait(1)
end
game:BindToClose(onShutDown)



players.PlayerAdded:Connect(leaderboardSetUp)
players.PlayerRemoving:Connect(save)

while true do
	wait(60)
	for _,player in ipairs(players:GetPlayers()) do
		coroutine.wrap(save)(player)
	end
end

Thank you.

2 Likes

Check your errors/warns. There should be some. Review the GetAsync and SetAsync documentation. GetAsync only accepts 1 arguement. SetAsync only accepts two. So your lines should be:

local s,r = pcall(datastore.GetAsync,datastore,key)

and

local s,r = pcall(datastore.SetAsync,datastore,key,value)

The way pcall works, is it accepts a function, and then the rest of the arguments are passed to that function. Another way to view this would be pcall = function(callback,...), where the callback is a function that will be called, and … will be passed as arguements. BUT, since we are calling a : function with a . (we are typing :GetAsync as .GetAsync becuase thats the only way to navigate to the function without calling it), we need to provide the datastore object as the second argument so it will be seen as “self” as per OOP rules, which state argument 1 in a : function is natively self. Which is why we call it as pcall(datastore[methodHere],datastore,...)

1 Like

Thank you! I never knew that GetAsync, and SetAsync had a limit of arguments.