Infinite yield problem on datastore2

Ok, so this is the last thing I can think of:

local remote = game:GetService("ReplicatedStorage").Events:WaitForChild("RemoteFunction") -- the remote function
local dataStore2 = require(game.ServerStorage:WaitForChild("DataStore2")) -- the data store 2 module script

dataStore2.Combine("DATA", "Inventory")

remote.OnServerInvoke = function(player)
    local success, err = pcall(function()
	    return dataStore2("Inventory", player)
    end)

    if success then
      return err
    end

    return warn(err)
end

If it produces a warning then it’s an issue with the module script itself (i assume)

oof it still doesn’t work i think it may be in the local script but im not sure

No, the local script is fine, it’s something else that I can’t understand

The client cannot access server-sided content (objects/instances) stored inside server-sided services (ServerStorage & ServerScriptService). It will simply return nil and yield forever (if you’re using WaitForChild.)

Also, I don’t even know why you are using it (it serves no purpose as you are not doing anything with inventoryStore).

If you want to accomplish this, send over the datastore information (as a number/string) to the client.

how do i do that?

Can you elaborate why you need to use datastore in this case?
You are not even using it in your provided code, only defining it.

alright so from the script you can tell that im using armor and im trying to use datastore2 to save the armor. If needed heres the datahandler, im trying to get the datastore2 module in serverstorage and use it to update the inventory.

local replicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local HttpService = game:GetService("HttpService")
local Players = game:GetService("Players")

local DataStore2 = require(ServerStorage:WaitForChild("DataStore2"))

DataStore2.Combine("Data", "Inventory", "Currency", "Level", "Exp", "ExpToLevel")

local defaultLevel = 1
local defaultexp = 0
local DefaultCurrencyAmount = 0
local DefaultHealthAmount = 150
local defaultStrength = 10

local expToLevelUp = function(level)
	return tonumber(100 * math.exp(level))
end

game.Players.PlayerAdded:Connect(function(player)

	--All the DataStores in here--
	local InventoryStore = DataStore2("Inventory", player)
	local CurrencyStore = DataStore2("Currency", player)
	local ExpStore = DataStore2("Exp", player)
	local LevelStore = DataStore2("Level", player)
	local replicatedDataFolder = Instance.new("Folder")
	replicatedDataFolder.Parent = replicatedStorage.ReplicatedData
	replicatedDataFolder.Name = player.UserId


	---------------------------------------------
	--STARTING THE INVENTORY FUNCTION--
	local inventoryString = Instance.new("StringValue")
	inventoryString.Parent = replicatedDataFolder
	inventoryString.Name = "Inventory"

	--Leaderstats--
	local leaderstats = Instance.new("Folder", player)
	leaderstats.Name = "leaderstats"

	local LevelValue = Instance.new("IntValue", leaderstats)
	LevelValue.Name = "Level"

	local expValue = Instance.new("IntValue", leaderstats)
	expValue.Name = "Exp"
	
	local expToLevel = Instance.new("IntValue", leaderstats)
	expToLevel.Name = "ExpToLevel"
	
	local Warrior = Instance.new("IntValue",leaderstats)
	Warrior.Name = "War"	
	Warrior.Value = defaultStrength
	
	
	----------------------------------------------


	--Functions--

	local function updateLevel(amount)
		player.leaderstats.Level.Value = amount
		replicatedStorage.Events.UpdateClientLevel:FireClient(player, amount)
	end

	local function updateEXP(exp)
		if exp >= expToLevelUp(LevelStore:Get(defaultLevel)) then
			ExpStore:Increment(expToLevelUp(LevelStore:Get(defaultLevel)) * -1)
			LevelStore:Increment(1)
			game.Workspace["Level Up"]:Play()
			game.StarterGui.Level.LevelUP.Visible = true
			wait(1)
			game.StarterGui.Level.LevelUP.Visible = false
		else
			player.leaderstats.Exp.Value = exp
		end
		
		local expAtNextLevel = expToLevelUp(LevelStore:Get(defaultLevel))

		local currentlyHave = ExpStore:Get(defaultexp)

		player.leaderstats.ExpToLevel.Value = expAtNextLevel - currentlyHave
	
	end

	local inventoryData = InventoryStore:Get({})
	inventoryString.Value = HttpService:JSONEncode(inventoryData)

	InventoryStore:OnUpdate(function(decodedData)
		inventoryString.Value = HttpService:JSONEncode(decodedData)
	end)

	local function updateClientCurrency(amount)
		replicatedStorage.Events.UpdateClientCurrency:FireClient(player, amount)
	end

	updateClientCurrency(CurrencyStore:Get(DefaultCurrencyAmount))

	CurrencyStore:OnUpdate(updateClientCurrency)
	--call functions right away one time
	updateLevel(LevelStore:Get(defaultLevel))
	updateEXP(ExpStore:Get(defaultexp))

	LevelStore:OnUpdate(updateLevel)
	ExpStore:OnUpdate(updateEXP)
	
end)

Firstly, I notice that you are trying to access StarterGui, which would be your first mistake.

Basically, everything inside StarterGui is cloned inside a folder called PlayerGui within the player when the player joins, you need to access their PlayerGui and not the StarterGui.

Secondly, I do not see any reason to use a RemoteFunction here, you can just store the armor’s name then reference it when the player joins, and so on. I assume you’re parenting the armor to their character.

well only when the player equips the armor they can equip it, where do i store the armor name?

In the datastore?..

Aren’t you already saving stuff there? I would assume you’d know where.

Im just trying to update the inventory

Perhaps I am missing something and then sorry for wasting your time.
But I see no reason as of now why you would need a ModuleScript for this.

You can also just save everything in a normal “Script” in ServerScriptService.

Example:

local datastore = game:GetService("DataStoreService")
local ds1 = datastore:GetDataStore("PlayerStats") --call this whatever you want

game.Players.PlayerAdded:Connect(function(plr)
	
	local playerStats = Instance.new("Folder", plr) --we make an empty folder within the player in game.Players.plr
	playerStats.Name = "playerStats"
	local data = Instance.new("IntValue", playerStats)
	data.Name = "Data"
	local inv = Instance.new("IntValue", playerStats)
	inv.Name = "Inventory"
    local currency = Instance.new("IntValue", playerStats)
	currency.Name = "Currency"
	local lvl = Instance.new("IntValue", playerStats)
	lvl.Name = "Level"
	local exp = Instance.new("IntValue", playerStats)
	exp.Name = "Exp"
	local exptl = Instance.new("IntValue", playerStats)
	exptl.Name = "ExpToLevel"
	
	local Datas
	local success, errormessage = pcall(function()
		Datas = ds1:GetAsync(plr.UserId)
	end)
	
	if success and Data then 
		wait(2)
		print("loading player data") --this will print if the data loaded succesfully, it will not if there is no data yet (first time they join)
		plr.playerStats.Data.Value = Data[1]
		plr.playerStats.Inventory.Value = Data[2]
		plr.playerStats.Currency.Value = Data[3]
		plr.playerStats.Level.Value = Data[4]
		plr.playerStats.Exp.Value = Data[5]
		plr.playerStats.ExpToLevel.Value = Data[6]
	else
		print("stats not loaded no stats found") --this will print if it is the first time they join, it will then set their empty/not existing data to whatever you put in here
		plr.playerStats.Data.Value = 0
		plr.playerStats.Inventory.Value = 0
		plr.playerStats.Currency.Value = 0
		plr.playerStats.Level.Value = 0
		plr.playerStats.Exp.Value = 0
		plr.playerStats.ExpToLevel.Value = 0
	end
	
end)

game.Players.PlayerRemoving:Connect(function(player) --if the player leaves it saves all their data
	
	local data = player.playerStats.Data.Value
	local inv = player.playerStats.Inventory.Value
	local currency= player.playerStats.Currency.Value
	local lvl = player.playerStats.Level.Value
	local exp = player.playerStats.Exp.Value
	local exptl = player.playerStats.ExpToLevel.Value
	ds1:SetAsync(player.UserId, {
		data,
		inv,
		currency,
		lvl,
		exp,
		exptl
	})
	
end)

You’ll probably have to update the script to fit your game and your current script but this is a working script that will save those 6 values for you in a datastore called ds1 within the script and the thing between () in case you want to access it with another script.

The values will also be accessable with the player in a folder called “playerStats”.

I hope this can bypass your problem of not being able to call your script within the ServerStorage. Because upon pressing play the ServerStorage and ServerScriptService become empty and your ModuleScript will be transported to some invisible thing that you can’t really access.
So whatever you do you can’t find a way to call “game.ServerStorage:WaitForChild(“DataStore2”)”

Again, I hope this can bypass your problem and just save it in an easier spot! Please let us know if this helped or not, we’re here to help!

well im using datastore2 to save objects, as for datastore1 only saves instances. The module handles all the values making it so i don’t need a player removing. And it also makes sure the player has the data before giving it to them

Can’t you save those objects in game.ReplicatedStorage? Then you can call them from other scripts.

Looking back at the first script you send,

I don’t know what the inside of your ModuleScript looks like but I don’t understand why you’re doing this:

local datastore2 = require(game.ServerStorage:WaitForChild("DataStore2"))

I don’t know if you’re doing this to access a child of your modulescript or if you’re trying to access it’s code.
If you’re trying to access a child I recommend (but I can’t see them so I don’t know for sure) saving them in ReplicatedService instead.
If you’re trying to access the code inside then I recommend going through this page to see how modulescripts can be accessed: ModuleScript | Documentation - Roblox Creator Hub