"invalid argument #1 to 'ipairs' (table expected, got nil)" Which should not be an error

Hello everybody! Let’s go straight to the problem, I have a script that saves player data:

local datastoreservice = game:GetService("DataStoreService")
local datastore = datastoreservice:GetDataStore("test7")



game.Players.PlayerAdded:Connect(function(player)
	
	--leaderstats
	
	local leaderstats = Instance.new("Folder")
	leaderstats.Parent = player
	leaderstats.Name = "leaderstats"
	
	local Money = Instance.new("IntValue")
	Money.Parent = leaderstats
	Money.Name = "Money"
	
--	local Rebirths = Instance.new("IntValue")
--	Rebirths.Parent = leaderstats
--	Rebirths.Name = "Rebirths"
--	Rebirths.Value = 0
	
	local Sharpening = Instance.new("IntValue")
	Sharpening.Parent = leaderstats
	Sharpening.Name = "Sharpening"
	Sharpening.Value = 0
	
	--Tools
	
	local Tools = Instance.new("Folder")
	Tools.Parent = player
	Tools.Name = "Tools"
	
	local EquipTool = Instance.new("StringValue", Tools)
	EquipTool.Name = "EquipTool"
	EquipTool.Value = "WoodKnife"
	
	local OwnedTools = Instance.new("Folder")
	OwnedTools.Parent = Tools
	OwnedTools.Name = "OwnedTools"
	
	local OwnedSharpening = Instance.new("Folder", player)
	OwnedSharpening.Name = "OwnedSharpening"
	
	local SharpeningUpgrd = Instance.new("StringValue")
	SharpeningUpgrd.Parent = Tools
	SharpeningUpgrd.Name = "SharpeningUpgrd"
	SharpeningUpgrd.Value = "Stone"
	
	--Just tool for TableTools
	
game:GetService("ReplicatedStorage"):WaitForChild("Tools"):FindFirstChild("WoodKnife"):Clone().Parent = OwnedTools
	
	--Creat Table For Tools 
	
	local OwnedToolsTable = {}
	
	
--	for i ,v in ipairs(OwnedToolsTable) do
--		local OwnedTool = game:GetService("ReplicatedStorage").Tools:FindFirstChild(tostring(v)):Clone()
--		OwnedTools.Parent = OwnedToolsTable
	--	end

	local tableOfData
	local success, errormessage = pcall(function()
		tableOfData = datastore:GetAsync(player.UserId)
	end)
	if success and tableOfData then -- we know that it is a returning player whom already played this game before
		for key, value in pairs(tableOfData) do
			print(key)
			print(value)
			Money.Value = tableOfData["Money"]
		  --Rebirths.Value = tableOfData["Rebirths"]
			Sharpening.Value = tableOfData["Sharpening"]
			SharpeningUpgrd.Value = tableOfData["SharpeningUpgrd"]
			EquipTool.Value = tableOfData["EquipTool"]
			OwnedToolsTable = tableOfData["OwnedToolsTable"]
		end	
			
			player.Backpack:ClearAllChildren()
			player.StarterGear:ClearAllChildren()
			if EquipTool.Value == "WoodKnife" then
				local WoodKnife = game.ReplicatedStorage.Tools.WoodKnife:Clone()
				WoodKnife.Parent = player.Backpack
				local WoodKnife2 = game.ReplicatedStorage.Tools.WoodKnife:Clone()
				WoodKnife2.Parent = player.StarterGear
				else
				local ToolSelect= game.ReplicatedStorage.Tools:FindFirstChild(EquipTool.Value):Clone()
				ToolSelect.Parent  = player.Backpack
				local ToolSelect2 = game.ReplicatedStorage.Tools:FindFirstChild(EquipTool.Value):Clone()
				ToolSelect.Parent  = player.StarterGear
			end
			

		for i, v in	ipairs(OwnedToolsTable) do
			local Tool =  game.ReplicatedStorage.Tools:FindFirstChild(tostring(v)):Clone()
		    Tool.Parent= OwnedTools
			end


		
	else -- we know that this player is new or their data got throttled (cached) or whatever you call it and have lost their data
		--sets the default value for new players

		Money.Value = 0
	  --Rebirths.Value = 0
		Sharpening.Value = 0
		SharpeningUpgrd.Value = "Stone"


	end

end)
game.Players.PlayerRemoving:Connect(function(player)
	
	local OwnedToolsTable = {}
	
	for i, v in ipairs(player.Tools.OwnedTools:GetChildren()) do
		table.insert(OwnedToolsTable, v.Name)				
	end
	
	local tableOfData = {
		["Money"] = player.leaderstats.Money.Value,
	--	["Rebirths"] = player.leaderstats.Rebirths.Value,
		["Sharpening"] = player.leaderstats.Sharpening.Value,
		["SharpeningUpgrd"] = player.Tools.SharpeningUpgrd.Value,
		["EquipTool"] = player.Tools.EquipTool.Value,
		["OwndeToolsTable"] = OwnedToolsTable,

	}


	local success, errormessage = pcall(function()
		print(tableOfData)
		datastore:SetAsync(player.UserId, tableOfData)
	end)
end)

It seems that everything is fine, but there is 1 line that creates an incomprehensible problem for me

		for i, v in	ipairs(OwnedToolsTable) do
			local Tool =  game.ReplicatedStorage.Tools:FindFirstChild(tostring(v)):Clone()
		    Tool.Parent= OwnedTools
			end

But the table cannot be empty, after the very first entry of the player into the game there is no error, but after player 2 enters the game gives this error

This line was supposed to force the script after the player exited to write data to the table (that is, with 100% something will be written in the table):

game:GetService("ReplicatedStorage"):WaitForChild("Tools"):FindFirstChild("WoodKnife"):Clone().Parent = OwnedTools

image

The console prints that the table is not empty

Where is my problem?

It looks like you misspelled the ["OwnedToolsTable"] key in your saved table.

-- line 122 and onward
local tableOfData = {
		["Money"] = player.leaderstats.Money.Value,
		--	["Rebirths"] = player.leaderstats.Rebirths.Value,
		["Sharpening"] = player.leaderstats.Sharpening.Value,
		["SharpeningUpgrd"] = player.Tools.SharpeningUpgrd.Value,
		["EquipTool"] = player.Tools.EquipTool.Value,

		-- ["Ownde..."] instead of ["Owned..."]
		["OwndeToolsTable"] = OwnedToolsTable, 

	}

It might be helpful to have constants for the keys or strongly type your saved table.

2 Likes

Thanks! This solved my problem (stupid though it was)

1 Like