Table Expected, got nil?

I’ve created a modular datastore system, in replacement for the datastore system which didn’t work before. It seems to work fine is some ways, but then I get this error:

joinHandler:37: invalid argument #1 to 'pairs', table expected, got nil

Line 37 is this line:

	for indexValueName, Value in pairs(userData["PlayerData-"..player.UserId]) do

In this line, I’m attempting to access a table automatically created by the module whenever the player joins, which is name “PlayerData-” .

I don’t know what the issue is, as it prints this:

Added Preset Values
All Data Fetched Successfully

The joinHandler script:

local userData = require(game.ServerStorage.userData)
game.Players.PlayerAdded:Connect(function(player)
	userData.AddPlayerData(player)
	userData.LoadInData(player)		
	local values = {}
	local ldbrd = Instance.new("Folder")
	ldbrd.Name = "leaderstats"
	ldbrd.Parent  = player
	local CRW =Instance.new("BoolValue")
	CRW.Parent = player
	CRW.Name = "CRW"
	local benefits = Instance.new("IntValue")
	benefits.Parent = player
	benefits.Name = "Benefits"
	local rank = Instance.new("StringValue")
	rank.Parent = player
	rank.Name  = "Rank"
	local spleefCoins = Instance.new("IntValue")
	spleefCoins.Parent = player
	spleefCoins.Name = "SpleefCoins"
	local wins = Instance.new("IntValue")
	wins.Parent = ldbrd
	wins.Name = "Wins"
	local Levels = Instance.new("NumberValue")
	Levels.Parent = player
	Levels.Name = "Level"
	local XP = Instance.new("NumberValue", Levels)
	XP.Name = "XP"
	local XP_Limit =Instance.new("NumberValue", Levels)
	XP_Limit.Name = "XP_Limit"
	local  Equipped = Instance.new("StringValue")
	Equipped.Parent = player
	Equipped.Name = "Equipped"
	local  EquippedEffect = Instance.new("StringValue")
	EquippedEffect.Parent = player
	EquippedEffect.Name = "EquippedEffect"
	for indexValueName, Value in pairs(userData["PlayerData-"..player.UserId]) do
		local TblOfValues = {CRW, benefits, rank, spleefCoins, wins, Levels, XP, XP_Limit, Equipped, Equipped}
		for i, v in pairs(TblOfValues) do
			if indexValueName == v.Name then
				v.Value = Value
			end
		end
	end

	for i, v in pairs(values) do
		v:GetPropertyChangedSignal("Value"):Connect(function()
			userData.UpdatePlayerData(player, v.Name, v.Value)
		end)
	end
	userData.FireInfomration(player)
end)

while wait(20) do
	userData.SaveAllData()
end
game.ReplicatedStorage.sendEquippedEffect.OnServerEvent:Connect(function(plr, isEquipped, name, multiplier)
	local EquippedVal = plr:WaitForChild("EquippedEffect")
	if EquippedVal then
		if isEquipped then
			local Character = plr.Character or plr.CharacterAdded:Wait()
			if Character then
				local HRP = Character:WaitForChild("HumanoidRootPart")
				local Effect = HRP:FindFirstChildOfClass("ParticleEmitter")
				if Effect then
					Effect:Destroy()
					local ChosenEffect = game.ReplicatedStorage.Effects:FindFirstChild(name):Clone()
					EquippedVal.Value = ""
					print("Equipped")
				end
			end
		end
	else
		local Character = plr.Character or plr.CharacterAdded:Wait()
		if Character then
			local HRP = Character:WaitForChild("HumanoidRootPart")
			local Effect = HRP:FindFirstChildOfClass("ParticleEmitter")
			if Effect then
				Effect:Destroy()
				local ChosenEffect = game.ReplicatedStorage.Effects:FindFirstChild(name):Clone()
				EquippedVal.Value = ChosenEffect.Name
				print("Equipped")
			end
		end
	end

end)

game.ReplicatedStorage.SendEquipped.OnServerEvent:Connect(function(plr,isEquipped, nameOfButton)
	local EquippedVal = plr:WaitForChild("Equipped")
	if EquippedVal then
		if isEquipped then
			EquippedVal.Value = nameOfButton
			print("Equipped Trail")
			game.ServerStorage.EquipTrail:Fire(nameOfButton)
		else
			EquippedVal.Value = ""
			print("Disabled Trail")
			game.ServerStorage.EquipTrail:Fire(nil)
		end
	end
end)


game.ReplicatedStorage.ProcessPurchase.OnServerEvent:Connect(function(plr, price, owned, name)
	if plr.SpleefCoins.Value >= price then
		game.ServerStorage.PassAlongOwnedTrails:Fire(owned)
		plr.SpleefCoins.Value -= price
		game.ServerStorage.EquipTrail:Fire(name)

	else
		print("Purchase Incomplete")
	end

end)

game.Players.PlayerRemoving:Connect(function(player)
	userData.SaveData(player)
end)

Modular Datastore/Leaderstats System

local module = {}
---This Module Handles Players Joining, Players Leaving and Backups
local DatastoreService = game:GetService("DataStoreService")
local PlayerDatastore = DatastoreService:GetDataStore("PDatastore_1")
local InventoryDatastore = DatastoreService:GetDataStore("InvStore_1")
local BackupPlayerDatastore = DatastoreService:GetDataStore("BackupPDataDatastore")
local BackupInventoryStore = DatastoreService:GetDataStore("BackupInvStore")
function module.AddPlayerData(Player)
	local PlayerTable = module["PlayerData-"..tostring(Player.UserId)]
	PlayerTable = {
		["SpleefCoins"] = 0,
		["CRW"] = false,
		["Wins"] = 0,
		["Benefits"] = 1,
		["Equipped"] = "1",
		["EquippedEffect"] = "1",
		["Level"] = "1",
		["Rank"] = "Newbie",
		["XP"] = 0,
		["XP_Limit"] = 30

	}
	local InventoryTable = module["Inventory-"..tostring(Player.UserId)]
	InventoryTable = {
		["Trails"] = {
			"1"
		},
		["Effects"] = {
			"1"
		}
	}
	print("Added Preset Data")
end

function module.LoadInData(Player)
	local PlayerUserId = Player.UserId
	local PlayerKey = "Player-"..PlayerUserId
	local PlayerData, InventoryData
	local success, errormessage = pcall(function()
		PlayerData = PlayerDatastore:GetAsync(PlayerKey)
		InventoryData = InventoryDatastore:GetAsync(PlayerKey)
	end)
	if success then
		if PlayerData ~= nil then
			module["PlayerData-"..PlayerUserId] = PlayerData
		end
		if InventoryData ~= nil then
			module["Inventory-"..PlayerUserId] = InventoryData
		end
		print("All Data Fetched Successfully!")

	else
		warn("This Error Occured While Fetching The Data: "..errormessage)		
	end
end


function module.UpdatePlayerData(Player, oldValueName, newValue)
	local PlayerTable = module["PlayerData-"..Player.UserId]
	for indexValue, Value in pairs(PlayerTable) do
		if indexValue == oldValueName then
			indexValue = newValue
		end
	end
end

function module.UpdateInventoryData(Player, oldValueName, newValue)
	local InventoryTable = module["Inventory-"..Player.UserId]
	for indexValue, Value in pairs(InventoryTable) do
		if indexValue ==  oldValueName then
			indexValue = newValue
		end
	end
end

function module.SaveAllData()
	local PlayerUserId 
	local PlayerKey
	for indexPlayer, Player in pairs(game.Players:GetPlayers()) do
		PlayerUserId = Player.UserId
		PlayerKey = "Player-"..PlayerUserId
		local PlayerTable = module["PlayerData-"..tostring(PlayerUserId)]
		local InventoryTable = module["Inventory-"..PlayerUserId]
		if PlayerTable then
			local success, errormessage = pcall(function()
				PlayerDatastore:SetAsync(PlayerKey, PlayerTable)
				BackupPlayerDatastore:SetAsync(PlayerKey, PlayerTable)
				InventoryDatastore:SetAsync(PlayerKey, InventoryTable)
				BackupInventoryStore:SetAsync(PlayerKey, InventoryTable)
			end)
			if success then
				print("Saved "..Player.Name.."'s Data Successfully")
			else
				wait("Error: "..errormessage)
			end
		end
	end
end

function module.SaveData(Player)
	local PlayerUserId = Player.UserId
	PlayerKey = "Player-"..PlayerUserId
	local PlayerTable = module["PlayerData-"..tostring(PlayerUserId)]
	local InventoryTable = module["Inventory-"..PlayerUserId]
	if PlayerTable then
		local success, errormessage = pcall(function()
			PlayerDatastore:SetAsync(PlayerKey, PlayerTable)
			BackupPlayerDatastore:SetAsync(PlayerKey, PlayerTable)
			InventoryDatastore:SetAsync(PlayerKey, InventoryTable)
			BackupInventoryStore:SetAsync(PlayerKey, InventoryTable)
		end)
		if success then
			print("Saved "..Player.Name.."'s Data Successfully")
		else
			wait("Error: "..errormessage)
		end
	end
end

function module.FireInfomration(Player)
	game.ReplicatedStorage.sendOwned:FireClient(Player, module["Inventory-"..tostring(Player.UserId)].Trails)
	game.ReplicatedStorage.sendOwnedEffects:FireClient(Player,	module["Inventory-"..tostring(Player.UserId)].Effects)
end

game.ReplicatedStorage.sendOwned.OnServerEvent:Connect(function(Player, owned)
	module["Inventory-"..tostring(Player.UserId)].Trails = owned
end)

game.ReplicatedStorage.sendOwnedEffects.OnServerEvent:Connect(function(Player, owned)
	module["Inventory-"..tostring(Player.UserId)].Effects = owned
end)


game:BindToClose(module.SaveAllData)

return module

I think the problem is that in your module you change the variable instead of the value attached to the key in module in module.AddPlayerData function.
Here is what I mean:

local PlayerTable = module["PlayerData-"..tostring(Player.UserId)] --PlayerTable is either will be a reference to to table attached to the key or nil.
PlayerTable = { --Here, you override the value attached to the PlayerTable variable but this doesn't change the table attached to the key in module.
	["SpleefCoins"] = 0,
	["CRW"] = false,
	["Wins"] = 0,
	["Benefits"] = 1,
	["Equipped"] = "1",
	["EquippedEffect"] = "1",
	["Level"] = "1",
	["Rank"] = "Newbie",
	["XP"] = 0,
	["XP_Limit"] = 30
}

Instead, it should be like this:

function module.AddPlayerData(Player)
	module["PlayerData-"..tostring(Player.UserId)] = {
		["SpleefCoins"] = 0,
		["CRW"] = false,
		["Wins"] = 0,
		["Benefits"] = 1,
		["Equipped"] = "1",
		["EquippedEffect"] = "1",
		["Level"] = "1",
		["Rank"] = "Newbie",
		["XP"] = 0,
		["XP_Limit"] = 30
	}
	module["Inventory-"..tostring(Player.UserId)] = {
		["Trails"] = {
			"1"
		},
		["Effects"] = {
			"1"
		}
	}
	print("Added Preset Data")
end
1 Like

Nevermind it appears to have stopped erroring, but now something else is occuring. it doesn’t set any of the values instanced in the joinHandler script to the table values, even though Implemented this:

	for indexValueName, Value in pairs(userData["PlayerData-"..tostring(player.UserId)]) do
		local TblOfValues = {CRW, benefits, rank, spleefCoins, wins, Levels, XP, XP_Limit, Equipped, Equipped}
		for i, v in pairs(TblOfValues) do
			if indexValueName == v.Name then
				v.Value = indexValueName
			end
		end
	end

I think I’ll move this to a seperate topic though