Attempt to index nil with "Clone"

Issue:

I have a folder of effects (particle emitters) within a folder in replicated storage called “Effects” and a script which handles the cloning of billboardGUI’s and particle emitters when the character is added. It was all working good until I introduced the effect’s shop, which then caused the joinHandler script to start erroring at line 70:

Line 70 of joinHandler Script:

local plrEffect = game.ReplicatedStorage.Effects:FindFirstChild(plr.EquippedEffect.Value):Clone()

As you can see, I believe it is saying that the EquippedEffect value for serializing saved trails is nil, which then points to another potential reason for the error taking place.

My datastore script handles the instancing of all important values and tables, and it also handles sending and fetching data from the datastore. The datastore has been causing me multiple problems before, and despite it being wiped of all errors, I still have a sneaking suspicion that it isn’t functioning the intended way.

Datastore Script:

local DS = game:GetService("DataStoreService") --- Gets Datastore Service
local CSS = DS:GetDataStore("ChaosSpleefStore_6")
local OwnedDatastore = DS:GetDataStore("OwnedDatastore_7")
local OwnedTrailsDatastore = DS:GetDataStore("OwnedDatastoreTrails")
local ownedPlaceHolder , ownedEffectsPlaceHolder = {}, {}
game.Players.PlayerAdded:Connect(function(plr)
	local owned = {}
	

	local ldbrd = Instance.new("Folder")
	ldbrd.Name = "leaderstats"
	ldbrd.Parent  = plr
	
	local CRW =Instance.new("BoolValue")
	CRW.Parent = plr
	CRW.Name = "CRW"
	
	local benefits = Instance.new("IntValue")
	benefits.Parent = plr
	benefits.Name = "Benefits"
	
	local rank = Instance.new("StringValue")
	rank.Parent = plr
	rank.Name = "Rank"

	local spleefCoins = Instance.new("IntValue")
	spleefCoins.Parent = plr
	spleefCoins.Name = "SpleefCoins"

	local wins = Instance.new("IntValue")
	wins.Parent = ldbrd
	wins.Name = "Wins"
	
	local Levels = Instance.new("NumberValue")
	Levels.Parent = plr
	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 = plr
	Equipped.Name = "Equipped"
	
	local  EquippedEffect = Instance.new("StringValue")
	EquippedEffect.Parent = plr
	EquippedEffect.Name = "EquippedEffect"
	
	local playeruserid = "Player_"..plr.UserId
	local data = {}
	local owned
	local s, e = pcall(function()
		data = CSS:GetAsync(playeruserid)
		owned = OwnedDatastore:GetAsync(playeruserid)
		ownedEffectsPlaceHolder =OwnedTrailsDatastore:GetAsync(playeruserid)
	end)
	if s then
		if data ~= nil  then
			local module = require(game.ServerStorage.ModuleScript)
			spleefCoins.Value = data[1] 
			wins.Value = data[2]
			benefits.Value = data[3] or 1
			Levels.Value = data[4] or 1
			XP.Value = data[5] or 0
			XP_Limit.Value = data[6] or 30
			CRW.Value = data[7] or false
			rank.Value = data[8] or "Newbie"
			Equipped.Value = data[9] or "1"
			EquippedEffect.Value = data[10] or "1"			
			ownedPlaceHolder = owned
		
			
			
		else
			spleefCoins.Value = 0
			wins.Value = 0
			benefits.Value = 1
			Levels.Value =  1
			XP.Value = 0
			XP_Limit.Value = 30
			CRW.Value = false
			rank.Value = "Newbie"
			Equipped.Value =   "1"
			EquippedEffect.Value =  "1"			
		end
	else
		error(e)
	end
	
	game.ReplicatedStorage.sendEquippedEffect:FireClient(plr, Equipped.Value)
	game.ReplicatedStorage.sendOwnedEffects:FireClient(plr, ownedEffectsPlaceHolder)

end)
game.ServerStorage.PassAlongOwnedTrails.Event:Connect(function(o)
	ownedPlaceHolder = o
end)

game.ServerStorage.PassAlongOwnedEffects.Event:Connect(function(owneed)
	ownedEffectsPlaceHolder = owneed
end)




function Save()
	local players = game.Players:GetPlayers()
	for _, player in pairs(players) do
		local userId = "Player_"..player.UserId
		local data = {player.SpleefCoins.Value, player.leaderstats.Wins.Value, player.Benefits.Value,player.Level.Value, player.Level.XP.Value, player.Level.XP_Limit.Value, player.CRW.Value,player.Rank.Value, player.Equipped.Value,player.EquippedEffect.Value}
		if data then
			-- wrap in pcall to handle any errors
			local success, result = pcall(function()
				-- SetAsync yields so will stall shutdown (@-@)
				CSS:SetAsync(userId, data)
				OwnedDatastore:SetAsync(userId, ownedPlaceHolder)
				OwnedTrailsDatastore:SetAsync(userId, ownedEffectsPlaceHolder)
			end)
			if not success then
				warn(result)
			else
				return true
			end   
		end
	end


end

while wait(10) do
	if Save()then
		print("Saved Data")
	end
end
game.Players.PlayerRemoving:Connect(function(player)
	Save()
	if Save() then
		print("Saved "..player.Name.."'s data before they left")
	end
end)

game:BindToClose(Save)

As you can see the datastore script also handles the instancing of the value in question, so it must be linked to this.

I’m unsure on the cause so any help is much appreciated.

Thanks in advance!

I have a feeling that the player hasn’t loaded in yet, so you need to add something that waits for the player to load in.

Ok I’ll try that, I’ll add waitforchilds in case all player values haven’t been configured yet

Just as EliteSniperBoss said. The player might not have loaded in. Also try doing this

local EquippedEffect = plr.EquippedEffect
local plrEffect = game.ReplicatedStorage.Effects:FindFirstChild(tostring(EquippedEffect.Value)):Clone()

Can you also show how Replicated storage looks like in the explorer?

I found the reason for the error, it’s linked to the datastore.

When the datastore instances all the values, no data is loaded in, and also none of the values are set to their preset values.

For example.

EquippedEffect’s value is nil when the player loads in, and in the folder there isn’t anything like that. which is why it’s erroring.

Datastore:

**local DS = game:GetService("DataStoreService") --- Gets Datastore Service
local CSS = DS:GetDataStore("ChaosSpleefStore_6")
local OwnedDatastore = DS:GetDataStore("OwnedDatastore_7")
local OwnedTrailsDatastore = DS:GetDataStore("OwnedDatastoreTrails")
local ownedPlaceHolder , ownedEffectsPlaceHolder = {}, {}
game.Players.PlayerAdded:Connect(function(plr)
	local owned = {}
	

	local ldbrd = Instance.new("Folder")
	ldbrd.Name = "leaderstats"
	ldbrd.Parent  = plr
	
	local CRW =Instance.new("BoolValue")
	CRW.Parent = plr
	CRW.Name = "CRW"
	
	local benefits = Instance.new("IntValue")
	benefits.Parent = plr
	benefits.Name = "Benefits"
	
	local rank = Instance.new("StringValue")
	rank.Parent = plr
	rank.Name = "Rank"

	local spleefCoins = Instance.new("IntValue")
	spleefCoins.Parent = plr
	spleefCoins.Name = "SpleefCoins"

	local wins = Instance.new("IntValue")
	wins.Parent = ldbrd
	wins.Name = "Wins"
	
	local Levels = Instance.new("NumberValue")
	Levels.Parent = plr
	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 = plr
	Equipped.Name = "Equipped"
	
	local  EquippedEffect = Instance.new("StringValue")
	EquippedEffect.Parent = plr
	EquippedEffect.Name = "EquippedEffect"
	
	local playeruserid = "Player_"..plr.UserId
	local data = {}
	local owned
	local s, e = pcall(function()
		data = CSS:GetAsync(playeruserid)
		owned = OwnedDatastore:GetAsync(playeruserid)
		ownedEffectsPlaceHolder =OwnedTrailsDatastore:GetAsync(playeruserid)
	end)
	if s then
		if data ~= nil  then
			local module = require(game.ServerStorage.ModuleScript)
			spleefCoins.Value = data[1] 
			wins.Value = data[2]
			benefits.Value = data[3] or 1
			Levels.Value = data[4] or 1
			XP.Value = data[5] or 0
			XP_Limit.Value = data[6] or 30
			CRW.Value = data[7] or false
			rank.Value = data[8] or "Newbie"
			Equipped.Value = data[9] or "1"
			EquippedEffect.Value = data[10] or "1"			
			ownedPlaceHolder = owned
		
			
			
		else
			spleefCoins.Value = 0
			wins.Value = 0
			benefits.Value = 1
			Levels.Value =  1
			XP.Value = 0
			XP_Limit.Value = 30
			CRW.Value = false
			rank.Value = "Newbie"
			Equipped.Value =   "1"
			EquippedEffect.Value =  "1"			
		end
	else
		error(e)
	end
	
	game.ReplicatedStorage.sendEquippedEffect:FireClient(plr, Equipped.Value)
	game.ReplicatedStorage.sendOwnedEffects:FireClient(plr, ownedEffectsPlaceHolder)

end)
game.ServerStorage.PassAlongOwnedTrails.Event:Connect(function(o)
	ownedPlaceHolder = o
end)

game.ServerStorage.PassAlongOwnedEffects.Event:Connect(function(owneed)
	ownedEffectsPlaceHolder = owneed
end)




function Save()
	local players = game.Players:GetPlayers()
	for _, player in pairs(players) do
		local userId = "Player_"..player.UserId
		local data = {player.SpleefCoins.Value, player.leaderstats.Wins.Value, player.Benefits.Value,player.Level.Value, player.Level.XP.Value, player.Level.XP_Limit.Value, player.CRW.Value,player.Rank.Value, player.Equipped.Value,player.EquippedEffect.Value}
		if data then
			-- wrap in pcall to handle any errors
			local success, result = pcall(function()
				-- SetAsync yields so will stall shutdown (@-@)
				CSS:SetAsync(userId, data)
				OwnedDatastore:SetAsync(userId, ownedPlaceHolder)
				OwnedTrailsDatastore:SetAsync(userId, ownedEffectsPlaceHolder)
			end)
			if not success then
				warn(result)
			else
				return true
			end   
		end
	end


end

while wait(10) do
	if Save()then
		print("Saved Data")
	end
end
game.Players.PlayerRemoving:Connect(function(player)
	Save()
	if Save() then
		print("Saved "..player.Name.."'s data before they left")
	end
end)

game:BindToClose(Save)

One error probably linked to the malfunctioning is this:

It keeps on warning. “Argument 2 missing or nil” What Have I done wrong?

On what line number are you getting that error?

1 Like

Where it says warn(result). It keeps on warning argument 2 missing or nil.

It’s within the save function

Before doing SetAync(), try printing the table named data. Does it return nil?

1 Like

I printed data’s content, and it all returned 0. Printing the data directly brought up some weird stuff

Wait that’s the issue. The 2nd argument for the saving is nil, so that’s causing the data store to warn me that. I should probably put in a check for that, and maybe preset some values