Invalid argument #1 to 'concat' (table expected, got string)?

Topic leading up to this issue:
How would i successfully split this table and convert it to a string

I’m trying to concatenate a table which has been split with a string, and its provoking the error in the title.

I’m not fully aware how table.concat works so this may be the reason why this is happening.

The section of the code handling this:

	elseif Command == "J:Warn" then
				print("Warning...")
				local Target = ArgsTable[2]
				if string.lower(Target) == "all" then	

					for indexPlayer, Player in pairs(game.Players:GetPlayers()) do
						if Player == plr then
							print("Will not warn, as target is admin")
						else
							local Head = Player.Character:WaitForChild("Head")
							if Head then
								local NewTable = table.remove(ArgsTable, 1)
								local ToJoin = table.concat(NewTable, " ")

								local WarningGuiClone = WarningBillboardGui:Clone()
								WarningGuiClone.Text.Text = "You Have Been Warned For: "..ToJoin
								
								local WarningGuiClone = WarningBillboardGui:Clone()
								WarningGuiClone.Text.Text = "You Have Been Warned For: "..string.split(table.concat(stringMsg, ArgsTable[3][2], " "))
								WarnEvent:FireClient(Player, ArgsTable[3])
								Player:WaitForChild("Warns").Value += 1
								if Player:WaitForChild("Warns").Value == MainModule.MaxWarns then
									Player:Kick("You Have Been Warned Too Many Times")
								end
								delay(10, function()
									WarningGuiClone:Destroy()
								end)
							end

						end
					end
				else
					local Found_Player = MainModule.FindClosestMatchString("PlayerSearch", game.Players:GetPlayers(), Target)
					if Found_Player ~= nil then
						local Head = Found_Player.Character:WaitForChild("Head")
						if Head then
							local NewTable = table.remove(ArgsTable, 1)
							local ToJoin = table.concat(NewTable, " ")

							local WarningGuiClone = WarningBillboardGui:Clone()
							WarningGuiClone.Text.Text = "You Have Been Warned For: "..ToJoin
							WarningGuiClone.Parent = Head
							WarnEvent:FireClient(Found_Player)
							Found_Player:WaitForChild("Warns").Value += 1
							if Found_Player:WaitForChild("Warns").Value == MainModule.MaxWarns then
								Found_Player:Kick("You Have Been Warned Too Many Times")
							end
							delay(10, function()
								WarningGuiClone:Destroy()
							end)

						end

					end
				end

Module:

local mainTable = { --Table to store all functions, permited Players and valid commands
	["permittedIDs"] = { ---Table to store IDs of all 
		366734064 --My User ID
	},
	["validCmds"] = { --Table to store all cmds, for checks
		"J:Kick", --kick cmd
		"J:Kill", --kill cmd
		"J:Warn", --warn cmd
		"J:Speed", -- speed cmd
		"J:JumpPower", --jump cmd
		"J:Insert", --tool inserrt cmd
		"J:Fling" --fling cmd

	},
	["MaxWarns"] = 3 --Max warns before kick

} 
local InsertService = game:GetService("InsertService")

--Functions--
function mainTable.FindClosestMatchString(typeofsearch, placeToSearch, String) --Search for closest match
	String = string.lower(String) -- make it comparable
	if typeofsearch == "PlayerSearch" then
		if placeToSearch ~= game.Players:GetPlayers() then
			placeToSearch = game.Players:GetPlayers() ---Not sure if neccessary, maybe if i make a mistake 
		end
		for indexPlayer, Player in pairs(placeToSearch) do --pairs loop
			if string.match(string.lower(Player.Name), "^"..string.lower(String)) then --return match
				return Player
			end
		end
	elseif typeofsearch == "CommandSearch" then
		local CMDtable = placeToSearch
		for indexCommand, Command in pairs(CMDtable) do -- pairs loop
			if string.match(String, "^"..string.lower(Command)) then --return match
				return Command
			end
		end
	end
end

function mainTable.BreakUpStringIntoSpaces(String) --String.gmatch method
	local Table = {}
	for word in string.gmatch(String, "%S+") do -- %S+ is the string pattern to split up into spaces (Will change pattern later)
		table.insert(Table, #Table +1, word)
	end
	return Table --return table full of broken up string
end

function mainTable.Instance(InstanceString, Destination, Name, InitalVal) -- Unneccessary, but I'm adding this anyway
	local InstanceCreated = Instance.new(InstanceString) --Instance the thing defined
	InstanceCreated.Parent = Destination --Parent it
	InstanceCreated.Name = Name --set name
	if InitalVal ~= nil  then
		InstanceCreated.Value = InitalVal ---Set value to val given
	else
		print("Not A Value")
	end
	return InstanceCreated --Make the part accessible
end

function mainTable.UnpackModel(Model, Destintation)
	local Children = Model:GetChildren()
	for indexChild, Child in pairs(Children) do
		Child.Parent = Destintation
	end
	return Children
end
function mainTable.InsertTool(ID, Player)
	local tool
	local success, errormsg = pcall(function()
		tool = InsertService:LoadAsset(ID)
	end)
	if success then
		print("Success")
	else
		warn(errormsg)
	end
	local Character = Player.Character or Player.CharacterAdded:Wait()
	if Character then
		tool = mainTable.UnpackModel(tool, Character)
		Character.Humanoid:EquipTool(tool:FindFirstChildOfClass("Tool"))
	end
end
return mainTable --Make it accessible to scripts

If you’re familiar with concatenation, the function behaves like it sounds. It will take all of the entries in an array (it must be an array), and concatenate them together with some delimiter defined by the second (optional) argument. The result is a string. Here’s an example

local array = {1, 2, 3, 4}
print(table.concat(array)) --> 1234

When no second argument is given, there is no delimiter and the entries are not separated in the string. Here’s another example, this time using the second optional argument. As noted before, this argument represents the intermittent string (delimiter) between all entries of the array.

local array = {1, 2, 3, 4}
print(table.concat(array, "; ")) --> 1; 2; 3; 4

Also notice that it will not apply the delimiter to the last entry (the 4 does not have a semicolon after it, like the rest do). This function can be very useful, and it’s especially useful if you’re looking for a quick-and-easy way to display the content of an array (as an alternative to unpack ).

For one example of good implementation of table.concat , you can view an old post here that uses it to solve a problem with strings.

So how come I’m not able to do:

local NewTable = table.remove(ArgsTable, 1) --Does this return a table?
local ToJoin = table.concat(NewTable, " ")
WarningGuiClone.Text.Text = "You Have Been Warned For: "..ToJoin

Looking at what you said, this should be alright. I’m not sure why the error is provoked.

The argsTable contains broken up words from the string sent from the player

Not quite sure either, probably because in line 2 of what you gave me its an empty string?

ArgsTable isn’t nil if that’s what you mean.

I’m not sure if table.remove returns a table either.

I meant the " " after NewTable. Not sure if thats the problem, try changing it for reference to "; "

Oh! I did the space because i want it to return the strings with spaces between each value within the table

I think you can remove the space and it’ll add the spaces automatically.

Alright, I’ll try that. (and ill mark solution if it works)

It didn’t work, but this post may’ve solved my problem

1 Like

table.remove does not return a table; it returns the Variant (any value type) that has been removed from that table.
Assuming your ArgsTable is correct, what you’ll want to do is this:

table.remove(ArgsTable, 1)
local ToJoin = table.concat(ArgsTable, " ")
WarningGuiClone.Text.Text = "You Have Been Warned For: "..ToJoin

However, yes: that will remove that first key/async pair from the entire table so it cannot be used in any other logic after the table.remove call.
You may want to research table cloning if this is an issue. Here’s a DevHub thread about it: https://developer.roblox.com/en-us/articles/Cloning-tables

Happy coding.

1 Like

Hmmm, will try. Thanks! :smile:

1 Like

Make sure to mark whatever findings you come across as a solution! :slight_smile: