104: Cannot store Array in data store. Data stores can only accept valid UTF-8 characters

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!

i want to make a module so everytime i make a game i will use it (or send it to the community)

  1. What is the issue? Include screenshots / videos if possible!

i keep getting this issue " 104: Cannot store Array in data store. Data stores can only accept valid UTF-8 characters.".

  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?

after a few topics i heard that you should use

Http:JSONDecode
-- and
Http:JSONEncode

but they dont work
here is my script!

local Data = {}

-- DATACORE MADE BY ALI
-- OPEN SOURCE, MODULE FOR FREE

--\\ Settings \\--
local DataSlots = 2 -- The Amount of slots where you can save Data
local DefaultDataSlotSaving_Loading = 1 -- the default slot to save/load data from

--\\ Variables \\--
local Datastore = game:GetService("DataStoreService")
local CustomData = Datastore:GetDataStore("CustomData")
local Http = game:GetService("HttpService")
local StoredData = {}

--\\ Private functions \\--

local function GetDataParentUsingName(DataName: string)
	if typeof(DataName) ~= "string" then
		error(`Module Error (unable to find name)`)
		return
	end
	
	for i, v in ipairs(StoredData) do
		if v[1] == DataName then
			return v[4]
		end
	end
	
end

--\\ functions \\--

function Data.CreateData(DataType: "StringValue"|"NumberValue"|"IntValue"|"BoolValue", Name: string, plr: Player, Value: number|string|boolean, parent: Instance?)
	if typeof(Name) ~= "string" then
		error(`Invalid Name, it must be a string`)
		return
	end
	if not game:GetService("Players"):FindFirstChild(plr.Name) then
		error(`Invalid Player, there must be a Player`)
		return
	end
	if DataType ~= "StringValue" then
		if DataType == "NumberValue" or DataType == "IntValue" or DataType == "BoolValue" then
			print("Succeed")
		else
			warn(`DataType is invalid, it must be a StringValue`)
		end
	elseif DataType ~= "NumberValue" then
		if DataType == "StringValue" or DataType == "IntValue" or DataType == "BoolValue" then
			print("Succeed")
		else
			warn(`DataType is invalid, it must be a NumberValue`)
		end
	elseif DataType ~= "IntValue" then
		if DataType == "NumberValue" or DataType == "StringValue" or DataType == "BoolValue" then
			print("Succeed")
		else
			warn(`DataType is invalid, it must be a IntValue`)
		end
	elseif DataType ~= "BoolValue" then
		if DataType == "NumberValue" or DataType == "IntValue" or DataType == "StringValue" then
			print("Succeed")
		else
			warn(`DataType is invalid, it must be a BoolValue`)
		end
	end
	
	if DataType == "StringValue" and typeof(Value) ~= "string" then
		warn('Invalid value for '..Name..', it must be a string ("this is a string")')
		return
	elseif DataType == "BoolValue" and typeof(Value) ~= "boolean" then
		warn('Invalid value for '..Name..', it must be a boolean ("true" or "false")')
		return
	elseif DataType == "NumberValue" and typeof(Value) ~= "number" then
		warn('Invalid value for '..Name..', it must be a number (3.6)')
		return
	elseif DataType == "IntValue" and typeof(Value) ~= "number" and math.round(Value) ~= Value then
		warn('Invalid value for '..Name..', it must be a integer (1)')
		return
	end
	
	if not parent then parent = script end
	
	if parent:FindFirstChild(Name) then
		warn(`Data already exists`)
	end
	
	table.insert(StoredData, {Name, Value, plr.Name, parent})
	local NewData = Instance.new(DataType, parent)
	NewData.Name = Name
	NewData.Value = Value
	
end

function Data.GetData(DataName: string)
	local parent = GetDataParentUsingName(DataName)
	if typeof(DataName) ~= "string" then
		warn("Invalid Name, it must be a string")
		return
	end
	if not parent:FindFirstChild(DataName) then
		warn("Unable to find data")
		return
	else
		return parent:FindFirstChild(DataName)
	end
end

function Data.GetDataTable(DataName: string)
	if typeof(DataName) ~= "string" then
		warn("Invalid Name, it must be a string")
	end
	
	local Parent = GetDataParentUsingName(DataName) 
	
	if not Parent:FindFirstChild(DataName) then
		warn("Unable to find data")
	else
		for i, v in ipairs(StoredData) do
			if v[1] == DataName then
				return v
			end
		end
	end
end

function Data.GetDataGlobalTable()
	print(StoredData)
	return
end

function Data.SaveData(DataName: string, Slot: number?, DataForPlayer: Player)
	if typeof(DataName) ~= "string" then
		warn("Invalid Name, it must be a string")
	end
	
	if not Slot then Slot = DefaultDataSlotSaving_Loading end
	
	local DataTable = Data.GetDataTable(DataName)
	
	local s, e = pcall(function()
		Http:JSONEncode(CustomData:SetAsync("TableValue_"..DataTable[1].."_Slot_"..tostring(Slot).."_UserId_"..DataForPlayer.UserId, DataTable))
	end)
	
	if e then
		warn("There is an error saving Data")
		warn(e)
	elseif s then
		print("Succesfully Saved Data")
	end
	
	return
end

function Data.LoadData(DataName: string, Slot: number?, DataForPlayer: Player)
	if typeof(DataName) ~= "string" then
		warn("Invalid Name, it must be a string")
	end
	
	if not Slot then Slot = DefaultDataSlotSaving_Loading end

	local DataTable = Data.GetDataTable(DataName)

	local s, e = pcall(function()
		Http:JSONDecode(CustomData:GetAsync("TableValue_"..DataTable[1].."_Slot_"..tostring(Slot).."_UserId_"..DataForPlayer.UserId))
	end)

	if e then
		warn("There is an error loading Data")
		warn(e)
	elseif s then
		print("Succesfully Loaded Data")
		return Data.GetData(DataName)
	end
end

function Data.ChangeData(DataName: string, Slot: number?, DataForPlayer: Player, DataToChange: number|string|boolean)
	if typeof(DataName) ~= "string" then
		warn("Invalid Name, it must be a string")
	end
	
	local DataInstance = GetDataParentUsingName(DataName):FindFirstChild(DataName)
	
	local DataType = DataInstance.ClassName
	
	if DataType ~= "StringValue" then
		if DataType == "NumberValue" or DataType == "IntValue" or DataType == "BoolValue" then
			print("Succeed")
		else
			warn(`DataType is invalid, it must be a StringValue`)
		end
	elseif DataType ~= "NumberValue" then
		if DataType == "StringValue" or DataType == "IntValue" or DataType == "BoolValue" then
			print("Succeed")
		else
			warn(`DataType is invalid, it must be a NumberValue`)
		end
	elseif DataType ~= "IntValue" then
		if DataType == "NumberValue" or DataType == "StringValue" or DataType == "BoolValue" then
			print("Succeed")
		else
			warn(`DataType is invalid, it must be a IntValue`)
		end
	elseif DataType ~= "BoolValue" then
		if DataType == "NumberValue" or DataType == "IntValue" or DataType == "StringValue" then
			print("Succeed")
		else
			warn(`DataType is invalid, it must be a BoolValue`)
		end
	end

	if DataType == "StringValue" and typeof(DataToChange) ~= "string" then
		warn('Invalid value for '..DataName..', it must be a string ("this is a string")')
		return
	elseif DataType == "BoolValue" and typeof(DataToChange) ~= "boolean" then
		warn('Invalid value for '..DataName..', it must be a boolean ("true" or "false")')
		return
	elseif DataType == "NumberValue" and typeof(DataToChange) ~= "number" then
		warn('Invalid value for '..DataName..', it must be a number (3.6)')
		return
	elseif DataType == "IntValue" and typeof(DataToChange) ~= "number" and math.round(Data) ~= Data then
		warn('Invalid value for '..DataName..', it must be a integer (1)')
		return
	end

	if not Slot then Slot = DefaultDataSlotSaving_Loading end

	local DataTable = Data.GetDataTable(DataName)

	local s, e = pcall(function()
		DataTable[2] = Http:JSONEncode(CustomData:SetAsync("TableValue_"..DataTable[1].."_Slot_"..tostring(Slot).."_UserId_"..DataForPlayer.UserId, DataToChange))
		DataInstance.Value = DataToChange
	end)

	if e then
		warn("There is an error saving Data")
		warn(e)
	elseif s then
		print("Succesfully Changed Data")
	end

	return
end

function Data.DeleteData(DataName: string)
	if typeof(DataName) ~= "string" then
		warn("Invalid Name, it must be a string")
	end
	
	local DataTable = Data.GetDataTable(DataName)
	DataTable = nil
end

return Data

Please do not ask people to write entire scripts or design entire systems for you. If you can’t answer the three questions above, you should probably pick a different category.

1 Like