Entire game breaking due to invisible mixed array table

I want to preface this by saying that I absolutely for sure know what a mixed table is, and how to prevent a problem like that from happening. What I am experiencing is beyond that. This problem somehow breaks the client sided remote function process for every player. This error is only ever seen on the client side when invoking a remote function on the client side to the server. Even when I am only passing strings or numbers in a function it returns an error saying that there is a mixed or non-array table. This is not an easy fix, and I have spent days trying to fix this.

This is the output and the args are everything that is being passed into the remote function, so even when a table is not being passed, it is throwing an error regarding a table. I have exhausted everything I know, and I can assure you that it is not as simple as finding a table that is incorrectly indexed. What I do is I have a remotefunction bound, and i pass a string with the name of the function within a module along with arguments THAT ARE NOT TABLES. The arguments are only ever strings or numbers. The server sided function is called and returns a value. I am getting the mixed table error EVEN WHEN A TABLE IS NOT RETURNED, meaning even if I return a bool it still tells me I have an error regarding a table. Hopefully I have been as clear as possible. https://gyazo.com/f08ae0b37cf83b7b413c73dbe9ed631c this is the function I am calling for the remote function. Let me know If I need to provide more information for someone to understand better what is going on.

1 Like

Mind showing us what you are returning?

Have you tried using a RemoteFunction in a blank Baseplate? Does it produce the same result?

We’ll have to see if it’s your code or it’s on Roblox’s end

1 Like

Here is the call function:
https://gyazo.com/af35943498be992f0c969ce8217f84d5

Here is an example function of what it returns:
https://gyazo.com/e7c1329c5227a4eb4418b2ed1ee730a8

This error occurs at randoms times with no preface or server side output.

2 Likes

I have no idea what your code does, I don’t know what those variables are, it makes no sense to me.

Can you try using print() and typeof() to see what is being return?

1 Like

Cannot convert mixed or non-array tables: keys must be strings is a DataStore error. When a client invokes a RemoteFunction, and the callback for that RemoteFunction on the server errors, then client will also receive that error (as in it will also be logged on the client’s console).

This has nothing to do with the arguments that you pass to that RemoteFunction from the client, but how you’re handling it on the server.

2 Likes

There is no output on the server though, and the server is not even handling any tables in some of the functions, so that is why I am getting confused. Also when i call the same functions in console as the ones from the remote function does there is no error, but when I do it through the remote function it gives that error on client side.

1 Like

I’ve linked 3 pieces of code, an output, explained my problem very thoroughly. It is quite obvious that I am attempting to achieve fixing my bug. You have also added nothing to this post. You just want to come to the forum to virtue signal instead of offering any help.

2 Likes

Transpiled code from the gyazos hoboj03 posted:

function network:get(...)
    --return func:InvokeServer(...)
    local args = {...}
    local nargs = select('#', ...)
    local ret, nret
    local s, r = pcall(function()
        local function procArgs(...)
            ret = {...}
            nret = select('#', ...)
        end
        procArgs(func:InvokeServer(unpack(args, 1, nargs))
    end)
    if s then
        return unpack(ret, 1, nret)
    else
        warn('Error Dump:')
        for i = 1, nargs do
            print('ARG', i)
            print_r(args[i])
        end
        error(r)
    end
end
network:bindFunction("PlayerDataFunction",function(plr,name,...)
    if not publicFunctions[name] then return end
    return datamodule[name](plr,...)
end)
datamodule.cdCheck = function(plr,abname,abpos)
    if not abname then return end
    if not abpos then return end
    local dat = datamodule.PlayerData[plr]
    if not dat.currentgod then return end
    local ability = dat.currentgod.AbilityList[abpos]
    if not ability then return end
    if dat.currentgod.AbilityList[abpos].cooldown == false then
        return false
    else
        return true
    end
end
89 : local onCooldown = network:get("PDS","cdCheck",abilityname,abpos)
90 :     if onCooldown == nil or onCooldown == true
91 :      then return end
3 Likes

I would like to call attention to the error in the console in the original post,

ReplicatedStorage.NetworkClient:90: Cannot convert mixed or non-array tables: keys must be strings

@hoboj03, what is line 90 in the first function, network:get, if this is applicable?

If you are not able to access your computer as of right now, that is understandable.

1 Like

https://gyazo.com/f10616d8d53f056e71ca3da914d1c4c1
This is the line that is calling the remote function and passes the arguments, which in turn calls the cdCheck function that was posted as a picture in a reply above.

2 Likes

Can I get confirmation that the function handling that invoke on the server uses the DataStore?

1 Like

I’m not entirely sure what you mean by this, but the datamodule is just a module where I house all of the main server handling stuff that changes the player’s table values. The player’s data is made within that module though.

2 Likes

One last thing: Can you remove the pcall in this function (for testing!):

function network:get(...)
    --return func:InvokeServer(...)
    local args = {...}
    local nargs = select('#', ...)
    local ret, nret
    local s, r = pcall(function() -- THIS PCALL
        local function procArgs(...)
            ret = {...}
            nret = select('#', ...)
        end
        procArgs(func:InvokeServer(unpack(args, 1, nargs))
    end)
    if s then
        return unpack(ret, 1, nret)
    else
        warn('Error Dump:')
        for i = 1, nargs do
            print('ARG', i)
            print_r(args[i])
        end
        error(r)
    end
end

It’s suppressing the actual line number of the error.

1 Like

The issue with this bug is that I have no idea when it will happen. The servers last for hours before the entire server breaks due to this bug to give the output. This is on the client side as well, so when you print( r ) it shows the line number just like the console log in the original post. I’m not sure if what youre asking for is different let me know.

2 Likes

A mixed or non-array table means a mixture of a table and dictionary, you should try reading this topic:

Apparently something mixed up while passing the table.

Situation is unclear; the most longest answer would be mapping out the events after time. Which could be really frustrating.

1 Like

Agreed that paragraphing is important, but you can always do it yourself in Notepad if it’s really as big of an issue as you argue it is. Either way, let’s get back on topic and be a bit nicer.

If all else fails, this method will split a mixed table into its array and map parts, letting you easily inspect and separate them for debugging purposes:

local function unmix(t) 
    local array = {unpack(t)} -- simple way of extracting array and preserving order
    local map = {} 
    for i, v in pairs(t) do
        -- we need to be careful of non consecutive numeric indices, these are part of the map and not the array
        if array[i] == nil then
            map[i] = v
        end
    end
    return array, map
end

I just wrote that on mobile, forgive any errors :sweat_smile:

5 Likes
datamodule.cdCheck = function(plr,abname,abpos)
    if not abname then return end
    if not abpos then return end
    local dat = datamodule.PlayerData[plr]
    if not dat.currentgod then return end
    local ability = dat.currentgod.AbilityList[abpos]
    if not ability then return end
    if dat.currentgod.AbilityList[abpos].cooldown == false then
        return false
    else
        return true
    end
end

I have to admit getting a fully clear idea of what you’re doing in relatively small time (and with many scattered snippets of code in some screenshots here and there) is difficult, but what I do notice is the following;

In the snippet above, there are 3 short-circuit statements that end up returning nil. If you are somehow using nil as table index you could be facing the issue of a mixed table as a result.

If it is returning nil, it cant be a table. Unless you are suggesting that the table is getting mixed and returning the mixed error before it can return the nil.

I see a lot of vararg use in the code above, and turning the result into tables. If at some point you’re creating tables/assigning indices from returned values, it could be an oversight that a nil value is used for this by accident where a bool is expected.

For a much clearer idea of what you’re actually doing, it’s easiest to provide an actual repro though since this way it’s hard to keep the oversight for anyone that’s not been working on this project for days.

The problem with creating the repro is I don’t know how it happens. It happens at random times. Servers could last 2 hours or 8 hours before this happens. The case is very obscure. Also at no point is a table returned, only indexed. So that function is just checking to see if the index exists in the table, if it was a mixed table would it not throw an error on the server side(which in my case has never given a server sided output), or just give the nil value that it is requesting?

2 Likes