Attempt to perform arithmetic (sub) on number and nil?

I am trying to make a buying system to buy glowsticks for a game of mine. In the script, it is not finding the price and is calling it as nil, when I can not think of why.

LOCALSCRIPT:
for i,v in pairs(script.Parent:GetChildren()) do
if v:IsA(“ImageButton”) then

	v.Cancel.MouseButton1Click:Connect(function()
		v.Visible = false
	end)
	v.Buy.MouseButton1Click:Connect(function()
		if game.Players.LocalPlayer.leaderstats.Cash.Value >= v.Price.Value then
		game.ReplicatedStorage.ShopBuy:FireServer(game.Players.LocalPlayer,v.Name,v.Price)
			else
			v.Visible = false
			end
			end)
			end
			end

SERVER SCRIPT:
game.ReplicatedStorage.ShopBuy.OnServerEvent:Connect(function(p,item,price)

p.leaderstats.Cash.Value = p.leaderstats.Cash.Value - price.Value

game.Lighting:WaitForChild(item):Clone().Parent = p.Backpack

end)

Anybody got a clue why? Am I missing something?

Could be related to you passing a reference to the player object to the server when this is unnecessary; Roblox does this already in the backend.

A major issue with your script is you are trusting the client. You are essentially passing the price of the value from the client, so a client can input zero, or even a negative number to get more cash.

Here is your revised script, free of bad practices.

local remote = game:GetService("ReplicatedStorage").ShopBuy

for _, child in ipairs(script.Parent:GetChildren()) do
    if child:IsA("GuiButton") then
        child.Cancel.Activated:Connect(function()
		    child.Visible = false
        end)

        child.Buy.Activated:Connect(function()
            remote:FireServer(child.Name)
			child.Visible = false
        end)
    end
end
local remote = game:GetService("ReplicatedStorage").ShopBuy
local items = game:GetService("ServerStorage").ShopItems

remote.OnServerEvent:Connect(function(player, item)
    if typeof(item) ~= "string" or not items:FindFirstChild(item) then
        print("Bad argument", item, typeof(item))
        return -- Just guarding against non-strings/bad name
    end
    
    local item = items[item]
    local total = player.leaderstats.Cash.Value - item.Price.Value
    if total >= 0 then
        player.leaderstats.Cash.Value = total
        item:Clone().Parent = player.Backpack
    end
end)

The server script assumes you have a folder in ServerStorage (because Lighting is not a service intended for storage) named ShopItems, and the same Price values you originally had in each tool.

2 Likes