"Keys Must Be Strings"

This shouldn’t be invokable either.

print(t={p=5}) errors

Note that Quenty’s example is just a BindableFunction which has the function connection missing.

e.g. he calls the bindablefunction but he didn’t connect a function to it yet. Probably for the sake of it being an example.

This is proper use of a BindableFunction:

Function = Instance.new("BindableFunction")

Function.OnInvoke = function(a,b,c) print(a,b,c) end

Function:Invoke(1,2,3) -- prints "1 2 3"

You can pass any arguments you want, also tables.

1 Like

Are you being confused by the whitespace? All whitespace is the same in Lua, so Quenty’s code is the same as this:

Function:Invoke({OwnedProductsSet = { [3453255] = true }})

We write it to a base 128 character instead of a base 256 character, and then escape.

\0
<
>
"
'
&

However, sometimes, very very rarely, when you save data, and shutdown the server, then reopen the server, and try to load the data, it’s corrupted, but somehow the extract function still manages to read it? Very rarely.

So there’s probably some combination of characters that datastore doesn’t like.

Last I checked, datastores don’t like characters above 127, because somewhere along the line the data gets treated as unicode.

I’ve learned to just base64 everything.

Quenty’s code is more like print({p=5})

Do you know for a fact that the data gets treated as unicode?

No I understand now.

I don’t use BindableFunctions very much and I didn’t understand that they had a function pointer assigned with OnInvoke and then Invoke is just a list of arguments. Does {OwnedProductsSet = { [3453255] = true }} evaluate the same as OwnedProductsSet? I know C has this behavior but I don’t depend on it when using other languages.

It’s a table where OwnedProductsSet is a key in the table, and the associated value is another table where numerical index 3453255 is true.

Last I checked was back when datastores first came out, so I don’t know if it has since been fixed. What I do remember is that the process of storing and loading data is a stupid mess, involving several layers of encoding.

If I remember correctly: During data retrieval, the data is requested from the cloud, and the cloud sends a response in JSON format. That gets decoded into some content, which contains the datastore data in JSON format (yes, two layers of JSON). Finally, that is decoded into the actual raw data. At some point in this process (probably the server response) the data is treated as unicode.

I have no idea if any of this is true anymore. I’d have to test it all over again, but I’m not interested enough to do it at the moment. It involves enabling studio access to datastores, and some Fiddling and/or Wiresharking.

I’m not sure what you mean. Curly-brackets in Lua always means a table is being created, and nothing else. So the code {OwnedProductsSet = {[3453255] = true}} creates a table that contains a “OwnedProductsSet” key, whose value is another table.

Consider the following code:

local data = {}
data.OwnedProductsSet = "foobar"
lookAtStuff(data)

This has the same result as:

local data = {OwnedProductsSet = "foobar"}
lookAtStuff(data)

Which has the same result as:

lookAtStuff({OwnedProductsSet = "foobar"})

And the function being called might look like:

function lookAtStuff(stuff)
    print(stuff.OwnedProductsSet) --> foobar
end

In C, this returns 1

blob.png

And this returns 0

blob.png

This is because the assignment operator = has the behavior of returning the data assigned as an rvalue.

Lua seems not to work like this.

if (p = true == true) then print(1) end

Produces an error. So I conclude that the answer to my question is that assignment in Lua returns nothing.

1 Like

This suggestion should be applied to RemoteEvent/RemoteFunction objects as well.

We’ve updated the message to this, which has a few more details:

15:58:22.372 - Workspace.Script:2: bad argument to 'Invoke' (cannot convert mixed or non-array tables: keys must be strings)

:slight_smile:

2 Likes

What if instead you let keys be ints?

The keys can either be strings or consecutive integers (1,2,3,4,etc.). Anything else will throw an error.

VolcanoINC was right–we also support arrays.

We’re currently serializing into a map with keys as strings, a type used in around 500 places in the code. Right now I’m not comfortable refactoring input, marketplace, datastore, players, replication, the primary class system, plugins, chat, studio’s explorer and input, intellesense, asset loading, and primary analytics. A change of this size would take the whole summer and would introduce regressions in ROBLOX’s whole codebase. As an intern, this is not a good first-week project.

I’ve filed a new bug report for this.

If there is a specific use-case that you specifically want to use mixed tables, please file a request in this forum, and it will also be added to our internal list. These changes can be done quicker than fixing the whole system. Thanks!

1 Like

TIL Quenty is wise beyond his years.

2 Likes

I think this error is still very uninformative, it doesn’t tell you what the datastore that failed is, the line of code, the script, the value or the key. I get this error very often and it always takes me much longer to solve than all of the other errors I receive, mainly due to the fact that it’s so difficult to understand or locate the source of.

It also doesn’t seem to make much grammatical or logical sense, before finding this post I was very confused as to what the error actually meant, as it seems to contradict itself:

Cannot convert non-array or mixed tables: keys must be strings

The ‘keys must be strings’ part seems like its referencing the entire sentence coming before the colon, and since arrays cannot have strings as keys, it seems like a direct contradiction of itself. On top of that, it doesn’t say anything about the fact that the datastore will accept arrays, or dictionaries, but not a mixture. It actually says cannot convert non-array tables, making it sound like your data must be an array, when in fact it can be a string indexed dictionary.

1 Like

Let’s continue the discussion here, it encompasses more error messages and is more up to date, and is placed in the right category:

Could you repost your issue on there? Thanks!