Attempt to index nil with a folder in datastore

Hello fellow Roblox devs, I am having an error sometimes when saving data with a server script.

It says that its attempting to index nil with a folder I made when the player joins
The error happens when I try to save the data when the player leaves.
image

I tried looking everywhere on the dev forum and trying other stuff to try to make it work (I’m a beginner at scripting :wink: ) but nothing worked.

Heres the whole script:

local DTS = game:GetService("DataStoreService")
local RunService = game:GetService("RunService")

local plrDataStore = DTS:GetDataStore("PlrDataStore") 

game.Players.PlayerAdded:Connect(function(Plr)
	local PlrUserId = "Player"..Plr.UserId
	
	-------------------------------------------------------------------------
	
	local Character = Plr.Character or Plr.CharacterAdded:Wait()
	
	local Values = Instance.new("Folder", Character)
	Values.Name = "Values"
	
	-------------------------------------------------------------------------
	
	local ClicksString = Instance.new("StringValue", Values)
	ClicksString.Name = "ClickString" --Currency
	ClicksString.Value = 0
	
	local ClickAdd = Instance.new("StringValue", Values)
	ClickAdd.Name = "ClickAdd"
	ClickAdd.Value = 1
	
	local ClickAddUpgradeLevel = Instance.new("StringValue", Values)
	ClickAddUpgradeLevel.Name = "ClickAddUpgradeLevel"
	ClickAddUpgradeLevel.Value = 0
	
	local ClickMultiplier = Instance.new("StringValue", Values)
	ClickMultiplier.Name = "ClickMultiplier"
	ClickMultiplier.Value = 1
	
	-------------------------------------------------------------------------
	
	local CriticalClickChanceLevel = Instance.new("StringValue", Values)
	CriticalClickChanceLevel.Name = "CriticalClickChanceLevel"
	CriticalClickChanceLevel.Value = 0
	
	-------------------------------------------------------------------------
	
	local ClickMultiplierCost = Instance.new("StringValue", Values)
	ClickMultiplierCost.Name = "ClickMultiplierCost"
	ClickMultiplierCost.Value = 25
	
	local CurrentClickMultiplier = Instance.new("StringValue", Values)
	CurrentClickMultiplier.Name = "CurrentClickMultiplier"
	CurrentClickMultiplier.Value = 1
	
	local NextClickMultiplier = Instance.new("StringValue", Values)
	NextClickMultiplier.Name = "NextClickMultiplier"
	NextClickMultiplier.Value = 2
	
	-------------------------------------------------------------------------
	
	local CriticalChanceCost = Instance.new("StringValue", Values)
	CriticalChanceCost.Name = "CriticalChanceCost"
	CriticalChanceCost.Value = 500
	
	local NextCriticalChance = Instance.new("StringValue", Values)
	NextCriticalChance.Name = "NextCriticalChance"
	NextCriticalChance.Value = 0.1
	
	local CriticalClickMaxChance = Instance.new("StringValue", Values)
	CriticalClickMaxChance.Name = "CriticalClickMaxChance"
	CriticalClickMaxChance.Value = 1000
	
	local CanBuyCriticalChance = Instance.new("BoolValue", Values)
	CanBuyCriticalChance.Name = "CanBuyCriticalChance"
	CanBuyCriticalChance.Value = true
	
	local CriticalChance = Instance.new("StringValue", Values)
	CriticalChance.Name = "CriticalChance"
	CriticalChance.Value = 0
	
	-------------------------------------------------------------------------
	
	local MusicEnabled = Instance.new("BoolValue", Values)
	MusicEnabled.Name = "MusicEnabled"
	MusicEnabled.Value = true
	
	-------------------------------------------------------------------------
	
	local ClickingRank = Instance.new("StringValue", Values)
	ClickingRank.Name = "ClickingRank"
	ClickingRank.Value = "Noob Clicker"
	
	-------------------------------------------------------------------------
	
	local TimesClicked = Instance.new("StringValue", Values)
	TimesClicked.Name = "TimesClicked"
	TimesClicked.Value = 0
	
	local Data
	--local success, errormessage = pcall(function()
		Data = plrDataStore:GetAsync(PlrUserId)
		--print(plrDataStore[PlrUserId])
		print(Data)
		print(PlrUserId)
	--end)
	
	if Data then
		Plr.Character.Values.ClickString.Value = Data["ClickString"]
		Plr.PlayerGui.ClickingGui.ClicksCounter.Text = "Clicks: "..Data["ClickString"]
		Plr.Character.Values.ClickAdd.Value = Data["ClickAdd"]
		Plr.Character.Values.ClickAddUpgradeLevel.Value = Data["ClickAddUpgradeLevel"]
		Plr.PlayerGui.ClickingGui.Frame.UpgradesFrame.ScrollingFrame.ClickAddUpgradeFrame.TimesBought.Text = "Times bought: "..Data["ClickAddUpgradeLevel"]
		Plr.Character.Values.ClickMultiplier.Value = Data["ClickMultiplier"]
		Plr.Character.Values.CriticalClickChanceLevel.Value = Data["CriticalClickChanceLevel"]
		Plr.PlayerGui.ClickingGui.Frame.UpgradesFrame.ScrollingFrame.CriticalClickChance.TimesBought.Text = "Times bought: "..Data["CriticalClickChanceLevel"]
		Plr.Character.Values.ClickMultiplierCost.Value = Data["ClickMultiplierCost"]
		Plr.PlayerGui.ClickingGui.Frame.UpgradesFrame.ScrollingFrame.ClickAddUpgradeFrame.CostLabel.Text = "Costs: "..Data["ClickMultiplierCost"].." Clicks"
		Plr.Character.Values.CurrentClickMultiplier.Value = Data["CurrentClickMultiplier"]
		Plr.Character.Values.NextClickMultiplier.Value = Data["NextClickMultiplier"]
		Plr.PlayerGui.ClickingGui.Frame.UpgradesFrame.ScrollingFrame.ClickAddUpgradeFrame.NextMultiplier.Text = "Next  Multiplier: x "..Data["CurrentClickMultiplier"].." → x "..Data["NextClickMultiplier"]
		Plr.Character.Values.CriticalChanceCost.Value = Data["CriticalChanceCost"]
		Plr.PlayerGui.ClickingGui.Frame.UpgradesFrame.ScrollingFrame.CriticalClickChance.CostLabel.Text = "Costs: "..Data["CriticalChanceCost"].." Clicks"
		Plr.Character.Values.NextCriticalChance.Value = Data["NextCriticalChance"]
		Plr.PlayerGui.ClickingGui.Frame.UpgradesFrame.ScrollingFrame.CriticalClickChance.NextChance.Text = "Next  Chance: %"..Data["CriticalChance"].." → %"..Data["NextCriticalChance"]
		Plr.Character.Values.CriticalClickMaxChance.Value = Data["CriticalClickMaxChance"]
		Plr.Character.Values.CanBuyCriticalChance.Value = Data["CanBuyCriticalChance"]
		if Plr.Character.Values.CanBuyCriticalChance.Value == false then
			Plr.PlayerGui.ClickingGui.Frame.UpgradesFrame.ScrollingFrame.Maxed.Visible = true
		end
		Plr.Character.Values.MusicEnabled.Value = Data["MusicEnabled"]
		Plr.Character.Values.ClickingRank.Value = Data["ClickingRank"]
		Plr.Character.Values.TimesClicked.Value = Data["TimesClicked"]
	end	
end)

game.Players.PlayerRemoving:Connect(function(Plr)
	local PlrUserId = "Player"..Plr.UserId
	local DataTable = {}
	
	for i, v in pairs(Plr.Character.Values:GetChildren()) do --The error is here
		DataTable[v.Name] = v.Value
		--print(i)
		--print(v)
	end
	
	local success, errormessage = pcall(function()
		--print(DataTable)
		--print(PlrUserId)
		plrDataStore:SetAsync(PlrUserId, DataTable) 
	end)
	
		if success then
			print("Data Saved!")
		else
		    warn("Data failed to save! "..errormessage)
		end
end)

Not reading through that whole script just to know what line 138 is. Could you highlight where exactly line 138 is and maybe provide the chunk it’s in? Like a few lines +/- line 138.

Nevermind about that, I actually see here: it’s that you’re adding your values to the character. Not sure why but if the character model is ever removed then you’re losing your folder and it won’t exist in the new one. You should be putting player data values either in the Player object itself or somewhere more accessible (Folder of ValueObjects or a ModuleScript, preference to the latter).

1 Like

Plr.Character.Values:GetChildren() here in the in pairs loop

Edit: Sure I’ll try.

I guess it works I’m not getting any errors anymore thanks!