Attempted to call require with invalid argument(s). - Server - ShopServer:7

I have remade my saving system for my shop script, and for some reason this error appears:

Attempted to call require with invalid argument(s). - Server - ShopServer:7

I can’t really quite figure out what went wrong in the script… And I am fairly certain that error prevents me from buying things in the shop too.

Here’s my script

local conf = game.ReplicatedStorage:WaitForChild("Configuration")
local currencyName = conf:WaitForChild("CurrencyName")
local startingCurrency = conf:WaitForChild("StartingCurrency")
local canBuyMultipleTimes = conf:WaitForChild("CanBuyItemMultipleTimes")

local modules = script:WaitForChild("ModuleScripts")
local SavingData = require(game.ServerScriptService.SavingData)
local CreateLeaderstats = require(modules:WaitForChild("CreateLeaderstats"))
local CreateTools = require(modules:WaitForChild("CreateTools"))
local BuyTool = require(modules:WaitForChild("BuyTool"))

local remotes = game.ReplicatedStorage:WaitForChild("RemoteEvents")
local buyToolRE = remotes:WaitForChild("BuyTool")

local equippedTools = {}

game.Players.PlayerAdded:Connect(function(plr)
	plr.CharacterAdded:Connect(function(char)
		char.ChildAdded:Connect(function(child)
			local equippedTool = char:FindFirstChildOfClass("Tool")
			equippedTools[plr] = equippedTool and equippedTool.Name
		end)
	end)

	local plrData = SavingData.LoadData(plr)
	local plrCash = plrData and plrData.Cash or startingCurrency.Value
	local plrTools = plrData and plrData.Tools or {}

	CreateLeaderstats(plr, plrCash)
	CreateTools(plr, plrTools)
end)

game.Players.PlayerRemoving:Connect(function(plr)
	SavingData.SaveData(plr, equippedTools[plr])
end)

game:BindToClose(function()
	for _, plr in pairs(game.Players:GetPlayers()) do
		SavingData.SaveData(plr, equippedTools[plr])
	end
end)

buyToolRE.OnServerEvent:Connect(function(plr, toolName)
	BuyTool(plr, toolName)
end)

Help would greatly be appreciated : D

1 Like

Send what’s inside of ModuleScripts and ServerScriptService.

Anything you require has to be module.

Here you go,

SavingData (Server script):

local DataStoreService = game:GetService("DataStoreService")
local conf = game.ReplicatedStorage:WaitForChild("Configuration")
local currencyName = conf:WaitForChild("CurrencyName")
local startingCurrency = conf:WaitForChild("StartingCurrency")
local dsKey = conf:WaitForChild("DatastoreKey")

local datastore = DataStoreService:GetDataStore(dsKey.Value)

-- Function to save player data
local function SaveData(player)
	if not player then
		return
	end

	local plrKey = player.UserId

	local plrCash = player:WaitForChild("leaderstats"):WaitForChild(currencyName.Value).Value

	-- Collect player's tools data
	local tools = {}
	for _, tool in ipairs(player.Backpack:GetChildren()) do
		table.insert(tools, tool.Name)
	end

	local plrData = { Cash = plrCash, Tools = tools }

	local success, err = pcall(function()
		datastore:SetAsync(plrKey, plrData)
	end)

	if not success then
		warn("Error saving " .. player.Name .. "'s (" .. plrKey .. ") data:\n" .. err)
	else
		print("Data saved successfully for player:", player.Name)
	end
end

-- Connect function to player leaving event
game.Players.PlayerRemoving:Connect(function(player)
	SaveData(player)
end)

game:BindToClose(function()
	for _, player in ipairs(game.Players:GetPlayers()) do
		SaveData(player)
	end
end)

-- Function to load player data
local function LoadData(player)
	if not player then
		return
	end

	local plrKey = player.UserId

	local dataFailedWarning = Instance.new("BoolValue")
	dataFailedWarning.Name = "DataLoadFailed"
	dataFailedWarning.Value = true
	dataFailedWarning.Parent = player

	local success, plrData = pcall(function()
		return datastore:GetAsync(plrKey)
	end)

	if success and plrData then
		-- Create leaderstats if not already present
		local leaderstats = player:FindFirstChild("leaderstats")
		if not leaderstats then
			leaderstats = Instance.new("Folder")
			leaderstats.Name = "leaderstats"
			leaderstats.Parent = player
		end

		local currency = leaderstats:FindFirstChild(currencyName.Value)
		if not currency then
			currency = Instance.new("IntValue")
			currency.Name = currencyName.Value
			currency.Parent = leaderstats
		end
		currency.Value = plrData.Cash or startingCurrency.Value

		-- Give the player their saved tools
		local backpack = player:WaitForChild("Backpack")
		for _, toolName in ipairs(plrData.Tools or {}) do
			local tool = game.ServerStorage:FindFirstChild(toolName)
			if tool then
				tool:Clone().Parent = backpack
			end
		end

		dataFailedWarning.Value = false
	else
		warn("Error loading " .. player.Name .. "'s (" .. plrKey .. ") data.")
	end

	dataFailedWarning:Destroy()
end

-- Connect function to player joining event
game.Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function()
		LoadData(player)
	end)
end)

BuyTool (ModuleScript):

local conf = game.ReplicatedStorage:WaitForChild("Configuration")
local currencyName = conf:WaitForChild("CurrencyName")
local canBuyMultipleTimes = conf:WaitForChild("CanBuyItemMultipleTimes")
local keepItemsOnDeath = conf:WaitForChild("KeepItemsOnDeath")

local tools = game.ReplicatedStorage:WaitForChild("Tools")
local coins = game.ReplicatedStorage:WaitForChild("Coins")
local gamepass = game.ReplicatedStorage:WaitForChild("Gamepass")

local remotes = game.ReplicatedStorage:WaitForChild("RemoteEvents")
local buyToolRE = remotes:WaitForChild("BuyTool")

function BuyTool(plr, toolName)
	local toolToBuy = nil

	-- Check if the tool is in the Tools category
	toolToBuy = tools:FindFirstChild(toolName)

	-- If not, check if it's in the Coins category
	if not toolToBuy then
		toolToBuy = coins:FindFirstChild(toolName)
	end

	-- If still not found, check if it's in the Gamepass category
	if not toolToBuy then
		toolToBuy = gamepass:FindFirstChild(toolName)
	end

	-- If the tool wasn't found in any category, return
	if not toolToBuy then
		warn("Tool '" .. toolName .. "' doesn't exist!")
		return
	end

	local toolConfig = toolToBuy:FindFirstChild("Configuration")
	if not toolConfig then
		warn("Tool '" .. toolName .. "' doesn't have a Configuration folder!")
		return
	end

	local toolPriceValue = toolConfig:FindFirstChild("Price")
	if not toolPriceValue then
		warn("Tool '" .. toolName .. "' doesn't have a Price value!")
		return
	end

	local plrCash = plr.leaderstats[currencyName.Value]
	local toolPrice = toolPriceValue.Value

	if plrCash.Value < toolPrice then
		warn("Player " .. plr.Name .. " (" .. plr.UserId .. ") doesn't have enough cash to buy '" .. toolName .. "'!")
		return
	end

	local plrTools = require(game.ReplicatedStorage.ModuleScripts.GetTools)(plr)

	-- Check if the player already owns the tool
	local alreadyOwnsTool = table.find(plrTools, toolName)

	if alreadyOwnsTool then
		-- Player already owns the tool, replace it
		local existingTool = plr.Backpack:FindFirstChild(toolName)
		if existingTool then
			existingTool:Destroy()
		end
	end

	-- Deduct the price from the player's cash balance
	plrCash.Value -= toolPrice

	-- Give the player the new tool
	local newTool = toolToBuy:Clone()
	newTool.Parent = plr.Backpack

	-- If configured to keep items on death, add the new tool to the starter gear
	if keepItemsOnDeath.Value then
		local starterGear = plr:FindFirstChild("StarterGear")
		if starterGear then
			newTool:Clone().Parent = starterGear
		end
	end

	-- Notify the client about the purchase
	buyToolRE:FireClient(plr, toolToBuy)
end

return BuyTool

CreateTools (ModuleScript):

local tools = game.ReplicatedStorage:WaitForChild("Tools")
local coins = game.ReplicatedStorage:WaitForChild("Coins")
local gamepass = game.ReplicatedStorage:WaitForChild("Gamepass")

local conf = game.ReplicatedStorage:WaitForChild("Configuration")
local keepItemsOnDeath = conf:WaitForChild("KeepItemsOnDeath")

function CreateTools(plr: Player)
	local plrTools = require(game.ReplicatedStorage.ModuleScripts.GetTools)(plr)

	-- Create tools from the Tools category
	for _, toolName in pairs(plrTools) do
		local plrTool = tools:FindFirstChild(toolName)
		if plrTool then
			plrTool:Clone().Parent = plr.Backpack
			if keepItemsOnDeath.Value == true then
				plrTool:Clone().Parent = plr.StarterGear
			end
		end
	end

	-- Create tools from the Coins category
	for _, tool in pairs(coins:GetChildren()) do
		if plr.Backpack:FindFirstChild(tool.Name) or plr.Character:FindFirstChild(tool.Name) then
			tool:Clone().Parent = plr.Backpack
			if keepItemsOnDeath.Value == true then
				tool:Clone().Parent = plr.StarterGear
			end
		end
	end

	-- Create tools from the Gamepass category
	for _, tool in pairs(gamepass:GetChildren()) do
		if plr.Backpack:FindFirstChild(tool.Name) or plr.Character:FindFirstChild(tool.Name) then
			tool:Clone().Parent = plr.Backpack
			if keepItemsOnDeath.Value == true then
				tool:Clone().Parent = plr.StarterGear
			end
		end
	end
end

return CreateTools

No, I meant in the explorer. What’s inside those?

Ohhh srry my bad

In ServerScriptService is my SavingData ServerScript, aswell as ShopServer, which inside it is a folder called ModuleScripts which contains the BuyTool and CreateTools modulescripts

You cannot require ServerScripts. That’s the problem. You’ll have to rewrite the system to account for this.

oh alright then, so that was the issue? that caused the Attempted to call require with invalid argument(s) error?

Yes, what were you trying to achieve requiring it anyways?

I used to have 2 module scripts for saving data, but it didn’t work too well for me, so I changed it to a ServerScript, and tried to replicate the way it was referenced there

1 Like

You should mark my post as a solution, so people know it’s solved.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.