104: Cannot store Dictionary in DataStore?

I’m getting the error ‘104: Cannot store Dictionary in DataStore’, I’m not sure if this is because i’m in studio testing mode or there is something wrong with my DataStore. This all worked fine yesterday so i’m really not sure.

3 Likes

According to this wiki page, datastore error 104 occurs when the value exceeds the maximum size of 64*1024 bytes. You may want to look into decreasing the character count of the dictionary.

So I should use more than one datastore variable?

Example
local DS1 = game:GetService("DataStoreService"):GetDataStore("DataStore1")
local DS2 = game:GetService("DataStoreService"):GetDataStore("DataStore2")

That’s a weird solution, and would take up double the number of requests. The value limit should be big enough to hold anything you need to save.

Can we see what you’re trying to save so we can figure out ways of optimising it?

I’m attempting to save the players:

  • Items,
  • Coins & Gems,
  • Pets,
  • Trails,
  • Equipped Item,
  • Equipped Pet,
  • Equipped Trail

What’s it look like?

This?

{
    Items = {"ItemId"};
    Coins = 0;
    Gems = 0;
    Trails/Pets = {"TrailId"/"PetId"}; -- suggest you put them in items
    Equipped = {Item = "ItemId"; Pet = "PetId"; Trail = "TrailId"};
}
1 Like

Close but more like this:

local Key = "Key" .. Plr.UserId
	local Data = DS:GetAsync(Key) or {
		
		-- // Trail stuff		
		
		Trails = {
			["None"] = {Particle = 0, Asset = 0, Rarity = "", Name = "None"},	
			},
		EquippedTrail = "None",
		
		-- // Pet stuff
		
		Pets = {
			["None"] = {Mesh = 0, Skin = 0, Asset = 0, Rarity = "Nothing"},		
		},
		
		EquippedPet = "None",
		
		-- // Item stuff		
		
		Inventory = {
			["Default"] = {Skin = 111867655, Asset = 1258605917, Rarity = "Default", Colour = Color3.fromRGB(97, 99, 102)},
		},		
		
		Equipped = "Default",
		
		-- // Currency stuff
		
		Cash = 100,
		Gems = 0,
	}
2 Likes

Ooh I can see why it takes up so much space

Store all the information about all items in the game in like a ModuleScript or something:

return {
    ItemId = {ItemDataHere}
}

Then after requiring the ModuleScript you can search for an item by its ID:

require(ModuleScript)["StarterItem"]

Just save the ‘Id’ of each item in the DataStore, like I wrote

To further preserve space, put everything you save into the Items table; instead of having 3 arrays, you’ll just have 1

8 Likes

I would recommend using an ID system as mentioned above for saving the players data; it seems redundant to specify the entirety of an item when that can be accessed from a ModuleScript in the server, ultimately saving space in the datastore.

4 Likes

That’s not enough data to go over the limit. Do you get this error saving the default inventory, or only when you’ve spammed a ton of items in the inventory?

Also, another issue I notice is that you’re trying to save a Color3. Roblox DataStores only support numbers, strings, booleans, and tables. Any Roblox types like Color3, BrickColor, NumberRange, etc can’t be stored – you’ll have to store them like Color = {1,1,0}.

5 Likes

@EchoReaper Are characters stored as 2 bytes per character in the datastore?

Characters are stored as 1 byte. The current version of the DataStore page had information removed, but if we look at an old version, we’ll see:

You cannot save any data which data size is more than 256 kibibytes, which equals 2 ^ 18 string characters.

256 kibibytes per 2^18 characters = 1/1024 kibibytes (1 byte) per character.

I don’t know where Roblox is getting the 64*1024 (65,536) bytes for max size mentioned on the Datastore Errors page, because with a limit of 260,000 characters per key that would mean a character is < 1 byte which is definitely incorrect.

Ascii works as a single byte, but how do they support unicode in that? Given emojis are a thing now, I assume they have to support at least more than a single byte per character of unicode data

Are you certain that it’s being stored as 1 byte? I’m pretty sure I’ve stored characters > 255 before. Storing them as a mix of 1 byte to more than 1 byte depending on the character would seem wonky.

At one point, Roblox only supported a limited amount of characters being saved to DataStores. Not sure what the case is now, but since the part I quoted from the wiki was removed, it could be because it was no longer accurate. TaaRt brought up a good point that it would have had to increase for unicode.

2 Likes

If you really need that much space you can split up your save file into multiple fragments each with the max size. Then you can save each to a different key. i.e. [userId]f[fragment index]
You’re also going to need to store in how many fragments there are in the first fragment or a manifest file in some other key. This solution requires a lot more safety measures though if you don’t want to clobber your player’s data (i.e. update one fragment and not the other).

1 Like