What is assertion failed?

I’m currently working on an inventory system using profile service and I am not too sure as to what I am doing. I wrote some code and everything works as intended except I keep getting this “assertion failed!” error message from my the second assertion of my :Set function

function PlayerDataHandler:Set(plr, key, value)
	local profile = getProfile(plr)
	assert(profile.Data[key], string.format("Data does not exist for key: %s", key))

	assert(type(profile.Data[key]) == type(value)) --assertion failed?

	profile.Data[key] = value
end

It was working perfectly fine yesterday before I tried making an equip and unequip function today.

function PlayerDataHandler:Equip(plr, itemName)
	self:Update(plr, "Inventory", function(current)
		if table.find(current, itemName) then
			table.remove(current, table.find(current, itemName))
			self:Update(plr, "Equipped", function(current)
				table.insert(current, itemName)
			end)
		else
			print(plr, "does not have", itemName )
		end
		table.insert(current, itemName)

		return current
	end)

	local item = game.ReplicatedStorage.Assets:FindFirstChild(itemName)
	if not item then return end
	
end

function PlayerDataHandler:Unequip(plr, itemName)
	self:Update(plr, "Equipped", function(current)
		if table.find(current, itemName) then
			table.remove(current, table.find(current, itemName))
			self:Update(plr, "Inventory", function(current)
				table.insert(current, itemName)
			end)
		else
			print(plr, "does not have", itemName )
		end
		table.insert(current, itemName)

		return current
	end)

	local item = game.ReplicatedStorage.Assets:FindFirstChild(itemName)
	if not item then return end
end

I honestly don’t completely understand what I’m doing with self:Update but the yt video I was following used it so I though it would be better for me to use it. I can barely find any info on assertion failed.

Any help would be greatly appreciated

2 Likes

Equip and Unequip functions without the redundant table.insert calls:

function PlayerDataHandler:Equip(plr, itemName)
	self:Update(plr, "Inventory", function(current)
		if table.find(current, itemName) then
			table.remove(current, table.find(current, itemName))
			self:Update(plr, "Equipped", function(equipped)
				table.insert(equipped, itemName)
			end)
		else
			print(plr, "does not have", itemName)
		end
		return current
	end)

	local item = game.ReplicatedStorage.Assets:FindFirstChild(itemName)
	if not item then return end
end

function PlayerDataHandler:Unequip(plr, itemName)
	self:Update(plr, "Equipped", function(current)
		if table.find(current, itemName) then
			table.remove(current, table.find(current, itemName))
			self:Update(plr, "Inventory", function(inventory)
				table.insert(inventory, itemName)
			end)
		else
			print(plr, "does not have", itemName)
		end
		return current
	end)

	local item = game.ReplicatedStorage.Assets:FindFirstChild(itemName)
	if not item then return end
end

Ensuring Data Initialization

Make sure that profile.Data["Inventory"] and profile.Data["Equipped"] are initialized properly:

function PlayerDataHandler:InitializeProfile(plr)
	local profile = getProfile(plr)
	profile.Data.Inventory = profile.Data.Inventory or {}
	profile.Data.Equipped = profile.Data.Equipped or {}
end
1 Like

Hi sorry for the late reply I’m not sure where exactly I should call Initialize profile but I did it right after I called equipped or add to inventory. Its not that the functions dont work, they work perfectly and also save as intended but I am getting this “assertion failed!” error that really doesnt do anything

bump :confused:
30char30char30char30char

Can you show where you’re calling :Set? I don’t see it in any of the snippets

In either case the assertion is failing because your types are mismatched, your profile.Data[key] could be, say, a string, whereas value could be something else like nil or boolean or etc

1 Like

Hi sorry for the late response set is called whenever Update is called

function PlayerDataHandler:Update(plr, key, callback)
	local profile = getProfile(plr)

	local oldData = self:Get(plr, key)
	local newData = callback(oldData)

	self:Set(plr, key, newData)
end

and I used self:Update for both my equip and unequip functions

Sorry for late response but let’s try this without assert

Modified Code without Assertions:

PlayerDataHandler:Set

function PlayerDataHandler:Set(plr, key, value)
	local profile = getProfile(plr)
	
	-- Temporarily comment out the assertions for debugging
	-- assert(profile.Data[key], string.format("Data does not exist for key: %s", key))
	-- assert(type(profile.Data[key]) == type(value), string.format("Type mismatch for key: %s. Expected %s but got %s", key, type(profile.Data[key]), type(value)))
	
	profile.Data[key] = value
end

PlayerDataHandler:Update

function PlayerDataHandler:Update(plr, key, callback)
	local profile = getProfile(plr)
	
	local oldData = self:Get(plr, key)
	print("Updating key: ", key, "Old Data Type: ", type(oldData))
	
	local newData = callback(oldData)
	print("New Data Type: ", type(newData))
	
	self:Set(plr, key, newData)
end

Ensure Proper Profile Initialization:

local function createProfileData()
	return {
		Inventory = {},
		Equipped = {}
	}
end

function getProfile(plr)
	local profile = profiles[plr]
	if not profile then
		profile = { Data = createProfileData() }
		profiles[plr] = profile
	end
	return profile
end

Call Profile Initialization:

Ensure that the profile is initialized before calling equip or unequip functions:

function PlayerDataHandler:Equip(plr, itemName)
	local profile = getProfile(plr) -- Ensure profile is initialized here
	self:Update(plr, "Inventory", function(current)
		print("Equip - Inventory Before: ", current)
		if table.find(current, itemName) then
			table.remove(current, table.find(current, itemName))
			self:Update(plr, "Equipped", function(equipped)
				table.insert(equipped, itemName)
				print("Equip - Equipped After: ", equipped)
				return equipped
			end)
		else
			print(plr, "does not have", itemName)
		end
		print("Equip - Inventory After: ", current)
		return current
	end)
	local item = game.ReplicatedStorage.Assets:FindFirstChild(itemName)
	if not item then return end
end

function PlayerDataHandler:Unequip(plr, itemName)
	local profile = getProfile(plr) -- Ensure profile is initialized here
	self:Update(plr, "Equipped", function(current)
		print("Unequip - Equipped Before: ", current)
		if table.find(current, itemName) then
			table.remove(current, table.find(current, itemName))
			self:Update(plr, "Inventory", function(inventory)
				table.insert(inventory, itemName)
				print("Unequip - Inventory After: ", inventory)
				return inventory
			end)
		else
			print(plr, "does not have", itemName)
		end
		print("Unequip - Equipped After: ", current)
		return current
	end)
	local item = game.ReplicatedStorage.Assets:FindFirstChild(itemName)
	if not item then return end
end
1 Like

Seems like now im getting a error that I never encountered before

11:27:11.318  Updating key:  Inventory Old Data Type:  table  ▼  {
                    [1] = "ClassicSword"
                 }  -  Server - PlayerDataHandler:205
  11:27:11.319  Updating key:  Equipped Old Data Type:  table {}  -  Server - PlayerDataHandler:205
  11:27:11.320  New Data Type:  nil nil  -  Server - PlayerDataHandler:208
-- There is a second nil because I made it also print new data itself after it prints the type
  11:27:11.320  New Data Type:  table {}  -  Server - PlayerDataHandler:208
--Above is the equip function output
  11:27:24.352  ServerScriptService.PlayerDataHandler:112: data does not exist for key: Equipped  -  Server -
--This is after I press unequip

Ok for whatever reason it seems to work now after I copy and paste your code and I dont seem to be getting the assertion faield error anymroe so ill mark this as solution

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