Datastore Error : DataStoreService: CantStoreValue: Cannot store Dictionary in data store. Data stores can only accept valid UTF-8 characters [SOLVED]

Hello everyone!

I am making a UGC Code System but I have a error,
DataStoreService: CantStoreValue: Cannot store Dictionary in data store. Data stores can only accept valid UTF-8 characters. API: SetAsync, Data Store: CodeDataStore (x5)

Script :

local DataStoreService	= game:GetService("DataStoreService")
local RedeemDataStore 	= DataStoreService:GetDataStore("RedeemDataStore")
local CodeDataStore		= DataStoreService:GetDataStore("CodeDataStore")

local maxTries 			= 5
local tryCooldown		= 2 --seconds

local CodeManager = {}

local function createCode(codeName,code,INDEX)
	if INDEX > maxTries then
		warn(tostring(codeName).." could not be saved!")
		return
	end
	local success = pcall(function()
		CodeDataStore:SetAsync(codeName,code)
	end)

	if success then
		print("success")
		return
	end
	
	task.wait(tryCooldown)
	createCode(codeName,code,INDEX+1) --recursion
end

local function checkCodeName(codeName)
	local success,code = pcall(function()
		CodeDataStore:GetAsync(codeName)
	end)
	
	if success and code and code["active"] > tick() or code["active"] < 0 then
		return true,code
	end
	
	return false
end

function CodeManager.newCode(codeName,itemId,count,creatorId,lifeTime) --lifetime in seconds or -1 for infinite
	local newCode = {
		itemId = itemId,
		itemC  = count,
		active = tick() + (lifeTime > 0 and lifeTime) or (-2*tick()),
		
		
		creatorId = creatorId;
	}
	
	createCode(string.lower(codeName),newCode,1)
end

local function giveItem(player,code)
	
end

local function playerRedeemCode(player,codeName,data,code)
	local newData = table.insert(data["codes"],codeName)
	local success = pcall(function()
		CodeDataStore:SetAsync(player.UserId,newData)
	end)
	
	giveItem(player,code)
end


function CodeManager.redeemCode(player,codeName)
	local codeName 	 = string.lower(codeName)
	local state,code = checkCodeName(codeName)
	
	if state == true then
		local success,data = pcall(function()
			CodeDataStore:GetAsync(player.UserId)
		end)
		
		if success then
			if data["codes"] and not table.find(data["codes"],codeName) then
				playerRedeemCode(player,codeName,data,code)
			end
		else
			RedeemDataStore:SetAsync(player.UserId,{})
			data = {codes = {}}
			playerRedeemCode(player,codeName,data,code)
		end
	end
end

return CodeManager

Please help me!

what’s the value that you are giving to the “codeName” and “code” parameters?

1 Like

I fixed it now!

--Credits: made by Nico_Nic77 / Crafter1338 (yt,discord)
----Services:
local ReplicatedStorage		= game:GetService("ReplicatedStorage")
local DataStoreService		= game:GetService("DataStoreService")
local MarketplaceService 	= game:GetService("MarketplaceService")
----Datastores:
local RedeemDataStore 		= DataStoreService:GetDataStore("RedeemDataStore")
local CodeDataStore			= DataStoreService:GetDataStore("CodeDataStore")
----Settings:
local maxTries 				= 2 --for recursion
local tryCooldown			= 1 --seconds
----module:

local module = {}

local function safeGetAsync(datastore,key,index)
	index = index or 0
	if index > maxTries then return {key,nil} end

	local succes,value = pcall(function()
		return datastore:GetAsync(key)
	end)

	if succes then
		return {key,value}
	end
	task.wait(tryCooldown)

	return safeGetAsync(index + 1) --recursive function
end

local function safeSetAsync(datastore,key,value,index)
	index = index or 0
	if index > maxTries then return false end

	local succes = pcall(function()
		return datastore:SetAsync(key,value)
	end)

	if succes then
		return true
	end
	task.wait(tryCooldown)

	return safeSetAsync(index + 1) --recursive function
end

function module.createCode(codeName,itemId,count,creatorId,lifeTime) --lifetime in seconds or -1 for infinite
	local newCode = {
		itemId = itemId,
		itemC  = count,
		active = tick() + (lifeTime > 0 and lifeTime or -2*tick()) ,
		creatorId = creatorId;
	}

	print(safeSetAsync(CodeDataStore,codeName,newCode))
end

function module.removeCode(codeName)
	local s = safeSetAsync(CodeDataStore, codeName, nil)
	return s
end

local function promptPlayer(player,assetId)
	MarketplaceService:PromptPurchase(player, assetId)
end

function module.redeemCode(player,codeName)
	local code = safeGetAsync(CodeDataStore,codeName)[2]

	if code then
		if code.active < tick() and code.active > 0 then
			module.removeCode(codeName)
			return
		end
		
		local check = safeGetAsync(RedeemDataStore,player.UserId)
		if typeof(check) ~= "table" then check = {} end
		if table.find(check,codeName) then print("player already used that code!") return end

		table.insert(check,codeName)
		local s = safeSetAsync(RedeemDataStore,player.UserId,check)

		if s then
			promptPlayer(player,code.itemId)
			return true
		end

		warn("error while reedeming code!")
	else
		return false
	end
end

return module

--Credits: made by Nico_Nic77 / Crafter1338 (yt,discord)

The main issue was that OP didn’t use code and codeName correctly! Always check your types my guys!

Hope this helps someone!

3 Likes