[ProfileService]: DataStore API error "104: Cannot store Dictionary in data store. Data stores can only accept valid UTF-8 characters."

I’m setting up new datastores for my game to add character customization, but I am getting these errors randomly.


I have no idea what I’m doing wrong. The scripts involved will be posted.
(Scripts that caused no issues before:)

game.Players.PlayerAdded:Connect(function(player)
	local OwnedGunsFolder = player:WaitForChild("OwnedGuns")
	
	wait(3)
	
	local data = StatManager:Get(player)
	
	if data then
		print(data.OwnedGuns)
		for i, v in pairs(data.OwnedGuns) do
			local ownedInsert = Instance.new("BoolValue")
			ownedInsert.Name = tostring(v)
			ownedInsert.Parent = OwnedGunsFolder
			table.remove(data.OwnedGuns, 1)
			print("got "..tostring(v))
		end
	end
end)
local GunBought = game:GetService("ReplicatedStorage"):WaitForChild("Events"):WaitForChild("GunPurchased")

GunBought.OnServerEvent:Connect(function(player, Gun)
	if  Gun == "LaserRifle" then
		GunPrice = 200
	end
	local data = StatsManager:Get(player)
	if data then
		local GunPurchased = Instance.new("BoolValue")
		GunPurchased.Name = Gun
		GunPurchased.Parent = player:WaitForChild("OwnedGuns")
		data.Lazercards -= GunPrice
	end
end)
game.Players.PlayerRemoving:Connect(function(player)
	pcall(function()
		local data = StatsManager:Get(player)
		if data then
			for i, v in pairs(player.OwnedGuns:GetChildren()) do
				table.insert(data.OwnedGuns, 1 ,v.Name)
				v:Destroy()
			end
			print("saved "..data.OwnedGuns)
		end
	end)
end)
game.Players.PlayerAdded:Connect(function(player)
	print("fired")
	
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player
	
	local OwnedGuns = Instance.new("Folder")
	OwnedGuns.Name = "OwnedGuns"
	OwnedGuns.Parent = player
	
	local OwnedShirts = Instance.new("Folder")
	OwnedShirts.Name = "OwnedShirts"
	OwnedShirts.Parent = player
	
	local OwnedPants = Instance.new("Folder")
	OwnedPants.Name = "OwnedPants"
	OwnedPants.Parent = player
	
	local Clothing = Instance.new("Folder")
	Clothing.Name = "clothing"
	Clothing.Parent = player
	
	local EquippedGun = Instance.new("StringValue")
	EquippedGun.Name = "EquippedGun"
	EquippedGun.Parent = player
	
	local Lazercards = Instance.new("IntValue")
	Lazercards.Name = "Lazercards"
	Lazercards.Parent = leaderstats
	
	local Cosmeticards = Instance.new("IntValue")
	Cosmeticards.Name = "Cosmeticards"
	Cosmeticards.Parent = leaderstats
	
	local Tags = Instance.new("IntValue")
	Tags.Name = "Tags"
	Tags.Parent = leaderstats
	
	local Victories = Instance.new("IntValue")
	Victories.Name = "Victories"
	Victories.Parent = leaderstats
	
	local Shirt = Instance.new("NumberValue")
	Shirt.Name = "Shirt"
	Shirt.Parent = Clothing
	
	local Pants = Instance.new("NumberValue")
	Pants.Name = "Pants"
	Pants.Parent = Clothing
	
	local SkinColor = Instance.new("Color3Value")
	SkinColor.Name = "SkinColor"
	SkinColor.Parent = Clothing
	
	wait(3)
	
	local data = StatManager:Get(player)
	
	if data then
		EquippedGun.Value = data.EquippedGun
		Lazercards.Value = data.Lazercards
		Victories.Value = data.Victories
		if data.Cosmeticards == nil then
			data.Cosmeticards = 0
		end
		if data.ShirtID == nil then
			data.ShirtID = 6536782130
		end
		if data.PantsID == nil then
			data.ShirtID = 129459077
		end
		if data.SkinColor == nil then
			data.SkinColor = Color3.new(163, 162, 165);
		end
		if data.OwnedShirts == nil then
			data.OwnedShirts = {6536782130}
		end
		if data.OwnedPants == nil then
			data.OwnedPants = {129459077}
		end
		Cosmeticards.Value = data.Cosmeticards
		Shirt.Value = data.ShirtID
		Pants.Value = data.PantsID
		SkinColor.Value = data.SkinColor
	else
		print(player.Name.."'s profile isn't loaded")
	end
end)

(Scripts that after adding, issues appeared.)

game.Players.PlayerAdded:Connect(function(player)
	local OwnedShirtsFolder = player:WaitForChild("OwnedShirts")
	
	wait(3)
	
	local data = StatManager:Get(player)
	
	if data then
		print(data.OwnedShirts)
		for i, v in pairs(data.OwnedShirts) do
			local ownedInsert = Instance.new("BoolValue")
			ownedInsert.Name = tostring(v)
			ownedInsert.Parent = OwnedShirtsFolder
			table.remove(data.OwnedShirts, 1)
			print("got "..tostring(v))
		end
	end
end)
game.Players.PlayerRemoving:Connect(function(player)
	pcall(function()
		local data = StatManager:Get(player)
		if data then
			for i, v in pairs(player.OwnedShirts:GetChildren()) do
				table.insert(data.OwnedShirts, 1 ,v.Name)
				v:Destroy()
			end
			print("saved "..data.OwnedShirts)
		end
	end)
end)
game.Players.PlayerAdded:Connect(function(player)
	local OwnedPantsFolder = player:WaitForChild("OwnedPants")
	
	wait(3)
	
	local data = StatManager:Get(player)
	
	if data then
		print(data.OwnedPants)
		for i, v in pairs(data.OwnedPants) do
			local ownedInsert = Instance.new("BoolValue")
			ownedInsert.Name = tostring(v)
			ownedInsert.Parent = OwnedPantsFolder
			table.remove(data.OwnedPants, 1)
			print("got "..tostring(v))
		end
	end
end)
game.Players.PlayerRemoving:Connect(function(player)
	pcall(function()
		local data = StatManager:Get(player)
		if data then
			for i, v in pairs(player.OwnedPants:GetChildren()) do
				table.insert(data.OwnedPants, 1 ,v.Name)
				v:Destroy()
			end
			print("saved "..data.OwnedPants)
		end
	end)
end)

(The middle-man script between these and ProfileService:)

local ProfileService = require(game.ReplicatedStorage.ProfileService)

local ProfileStore = ProfileService.GetProfileStore(
	"Player",
	{
		Lazercards = 0;
		OwnedGuns = {"StarterPistol"};
		EquippedGun = "StarterPistol";
		Victories = 0;
		Cosmeticards = 0;
		ShirtID = 6536782130;
		PantsID = 129459077;
		SkinColor = Color3.new(163, 162, 165);
		OwnedShirts = {6536782130};
		OwnedPants = {129459077};
	}
)

local Profiles = {}

local function OnPlayerAdded(player)
	local profile = ProfileStore:LoadProfileAsync(
		"Player_"..player.UserId,
		"ForceLoad"
	)
	
	if profile then
		profile:ListenToRelease(function()
			Profiles[player] = nil
			player:Kick()
		end)
		
		if player:IsDescendantOf(Players) then
			Profiles[player] = profile
		else
			profile:Release()
		end
	else
		player:Kick()
	end
	
end

local function OnPlayerRemoving(player)
	local profile = Profiles[player]
	if profile then
		profile:Release()
	end
end

Players.PlayerAdded:Connect(OnPlayerAdded)
Players.PlayerRemoving:Connect(OnPlayerRemoving)

local DataManager = {}

function DataManager:Get(player)
	local profile = Profiles[player]
	
	if profile then
		return profile.Data
	end
end

return DataManager
1 Like

You are able to store dictionaries. The issue here is that she is trying to save a Color3 (SkinColor).

1 Like

Ah ok, how would I store the skin color?

You should be able to store the R,G,B properties of Color3 as a number (0-1). You can then use Color3.new() to reconstruct it.

2 Likes

came here after running into same issue, would recommend storing the HTML value as a string and using that to recreate the color

That’s actually a really good idea, might do that when I get the motivation to work on that project again.