Attempt to index nil with len

local Admins = {
	206143181;
}

local CmdsPerms = {}

local Prefix = "/"

local function findPlr(name)
	
	for _, plr in pairs(game.Players:GetPlayers()) do

		if string.lower(string.sub(plr.Name,1,name:len())) == name then

			return plr

		end

	end
	
	return false

end

game.Players.PlayerAdded:Connect(function(plr)
	
	plr.Chatted:Connect(function(msg)
		
		msg = string.lower(msg)
		
		local arg = string.split(msg," ")
		
		local cmdname = arg[1]
		
		-- Staff Cmds
		
		if cmdname == Prefix .. "kick" and table.find(Admins,plr.UserId) then
			
			local PlrToKick = findPlr(arg[2])
			
			if PlrToKick then
				
				PlrToKick:Kick()
				
			end
			
		elseif cmdname == Prefix .. "kickall" then
			
			for _, currentplr in pairs(game.Players:GetPlayers()) do
				
				if not table.find(Admins,currentplr.UserId) then
					
					currentplr:Kick()
					
				end
				
			end
			
		end
		
		-- Public Cmds
		
		if cmdname == Prefix .. "tp" and plr:GetAttribute("CmdPerms") == true or table.find(Admins,plr.UserId) then
			
			local PlrToTp = findPlr(arg[2])
			
			local PlrToTpTo = findPlr(arg[3])
			
			if PlrToTp and PlrToTpTo then
				
				PlrToTp.Character:PivotTo(CFrame.new(PlrToTpTo.Character.WorldPivot.Position))
				
			end
			
		end
		
	end)
	
end)

image

I cant figure what is causing this issue arg 2 is not nil its p bc i coded it so you dont need to write the entire name

1 Like

I don’t necessarily understand why you’re doing all of this to match the player’s name instead of just if string.lower(plr.Name) == string.lower(name) then

Also, are you sure both args[2] and args[3] are strings that exist? I’m assuming it’s args[3] in the tp command that is broken, but it could be args[2] in the kick or tp command. Either way, maybe one of them didn’t get the argument input, therefore the name parameter in the function is nil.

i have printed multiple times and it results in a string

what does arg give when you print it?

p, because i made it so you dont have to write the whole name

Did you try printing name in the function?

if all arg prints is p, then that’s why you’re getting that error. You should be getting a table

should i just use the alvinblox tut?

i mean you could, but it would be better if you read the documentation, because i don’t think you’ll learn as much if you are just copying a tutorial

which documentation?

extra text

probably the one about strings, but to be honest im still confused on what’s working and what’s not.
string | Roblox Creator Documentation

copy the script from my code and test it out to see

looks fine, i just made a few tweeks to it:

local Admins = {
	206143181;
}

local CmdsPerms = {}

local Prefix = "/"

local function findPlr(name)

	for _, plr in pairs(game.Players:GetPlayers()) do

		if string.lower(string.sub(plr.Name,1,name:len())) == name then

			return plr

		end

	end

	return false

end

game.Players.PlayerAdded:Connect(function(plr)

	plr.Chatted:Connect(function(msg)

		msg = string.lower(msg)

		local arg = string.split(msg," ")
		
		print(arg)
		
		local cmdname = arg[1]

		-- Staff Cmds

		if cmdname == Prefix .. "kick" and table.find(Admins,plr.UserId) then

			local PlrToKick = findPlr(arg[2])

			if PlrToKick then

				PlrToKick:Kick()

			end

		elseif cmdname == Prefix .. "kickall" and table.find(Admins,plr.UserId) then

			for _, currentplr in pairs(game.Players:GetPlayers()) do

				if not table.find(Admins,currentplr.UserId) then

					currentplr:Kick()

				end

			end

		end

		-- Public Cmds

		if cmdname == Prefix .. "tp" and plr:GetAttribute("CmdPerms") == true or table.find(Admins,plr.UserId) then
			
			if #arg ~= 3 then return end
			
			local PlrToTp = findPlr(arg[2])

			local PlrToTpTo = findPlr(arg[3])

			if PlrToTp and PlrToTpTo then

				PlrToTp.Character:PivotTo(CFrame.new(PlrToTpTo.Character.WorldPivot.Position))

			end

		end

	end)

end)
1 Like

yes i just realized its nil*…*

tell me if this works for you
extra characters

how would i do this for a cmd like /kick and that a kick msg would be optional

you would probably just add the kick messages after the name with a space, then add that to the arguments, so basically you would do:

local Admins = {
	206143181;
}

local CmdsPerms = {}

local Prefix = "/"

local function findPlr(name)

	for _, plr in pairs(game.Players:GetPlayers()) do

		if string.lower(string.sub(plr.Name,1,name:len())) == name then

			return plr

		end

	end

	return false

end

game.Players.PlayerAdded:Connect(function(plr)

	plr.Chatted:Connect(function(msg)

		msg = string.lower(msg)

		local arg = string.split(msg," ")
		
		print(arg)
		
		local cmdname = arg[1]

		-- Staff Cmds

		if cmdname == Prefix .. "kick" and table.find(Admins,plr.UserId) then

			local PlrToKick = findPlr(arg[2])

			if PlrToKick then

				PlrToKick:Kick(arg[3] or '')

			end

		elseif cmdname == Prefix .. "kickall" and table.find(Admins,plr.UserId) then

			for _, currentplr in pairs(game.Players:GetPlayers()) do

				if not table.find(Admins,currentplr.UserId) then

					currentplr:Kick(arg[2] or '')

				end

			end

		elseif cmdname == Prefix .. "tp" and plr:GetAttribute("CmdPerms") == true or table.find(Admins,plr.UserId) then
			
			if #arg ~= 3 then return end
			
			local PlrToTp = findPlr(arg[2])

			local PlrToTpTo = findPlr(arg[3])

			if PlrToTp and PlrToTpTo then

				PlrToTp.Character:PivotTo(CFrame.new(PlrToTpTo.Character.WorldPivot.Position))

			end

		end

	end)

end)
1 Like

Ok now I tried the kill cmd and it doesnt work and also it doesnt give any error

local Admins = {
	206143181;
}

local CmdsPerms = {}

local Prefix = "/"

local function findPlr(name)
	
	for _, plr in pairs(game.Players:GetPlayers()) do

		if string.lower(string.sub(plr.Name,1,name:len())) == name then
			
			return plr

		end

	end

end

game.Players.PlayerAdded:Connect(function(plr)
	
	plr.Chatted:Connect(function(msg)
		
		msg = string.lower(msg)
		
		local args = string.split(msg," ")
		
		local cmdname = args[1]
		
		-- Staff Cmds
		
		if cmdname == Prefix .. "kick" and table.find(Admins,plr.UserId) then
			
			if #args ~= 2  then return end
			
			local PlrToKick = findPlr(args[2])
			
			if PlrToKick then
				
				PlrToKick:Kick(args[3] or "")
				
			end
			
		elseif cmdname == Prefix .. "kickall" then
			
			for _, currentplr in pairs(game.Players:GetPlayers()) do
				
				if not table.find(Admins,currentplr.UserId) then
					
					currentplr:Kick()
					
				end
				
			end
			
		end
		
		-- Public Cmds
		
		if cmdname == Prefix .. "tp" and plr:GetAttribute("CmdPerms") == true or table.find(Admins,plr.UserId) then
			
			if #args ~= 3 then return end
			
			local PlrToTp = findPlr(args[2])
			
			local PlrToTpTo = findPlr(args[3])
			
			if PlrToTp and PlrToTpTo then
				
				PlrToTp.Character:PivotTo(CFrame.new(PlrToTpTo.Character.WorldPivot.Position))
				
			end
			
		elseif cmdname == Prefix .. "kill" and plr:GetAttribute("CmdPerms") == true or table.find(Admins,plr.UserId) then
			
			if #args ~= 2 then return end
			
			local PlrToKill = findPlr(args[2])
			
			if PlrToKill then
				
				PlrToKill.Character.Humanoid.Health = 0
				
				print(plr.DisplayName .. " killed " .. PlrToKill.DisplayName)
				
			end
			
		elseif cmdname == Prefix .. "damage" or cmdname == Prefix .. "dmg" and plr:GetAttribute("CmdPerms") == true or table.find(Admins,plr.UserId) then
			
			if #args ~= 3 then return end
			
			local PlrToDmg = findPlr(args[2])
			
			local DmgAmount = args[3]
			
			if PlrToDmg and type(DmgAmount) == "number" then
				
				DmgAmount = tonumber(DmgAmount)
				
				PlrToDmg.Character.Humanoid:TakeDamage(DmgAmount)
				
			end
			
		end
		
	end)
	
end)

remove the line that says:

if #args ~= 2  then return end

Why would I do that if I want to ensure the findplr function doesn’t error