Issue with Table indexing not working correctly

Hello, I am currently developing a system for a Bus Shift style game and I am stumbling across an issue with a script involving table indexing (in this case getting values from it).

In short, this system keeps “Chapas” (“Chapas” are basically groups of Timetables for a driver/bus during the shift) and distributes them to buses from an UI which is controlled by an “operator”. The bus then receives the “Chapa” and from there it starts it’s journey when the driver configures the proper destination.

The way it handles Timetables is through “UniqueIDs”, that are registered as the Order in the Timetable Array (Stored in another script)

The part of the system where I’m having the issue is where it changes to the next Timetable inside the “Chapa”. When it changes to the next Timetable it will wait for the driver to set the next destination that corresponds to the destination in the next Timetable. This is where I get my error!

This is where it changes to the next Timetable, as you can see there is a protected function that exists in case there are no more Timetables left:

nextEvent.Event:Connect(function()
	local Timetable = {}
	Timetable = workspace.Timetables.GetTimetableSERVER:Invoke()
	Timetable[script.Parent.Parent.TimetableUniqueID.Value][4] = false
	workspace.Timetables.WriteToTimetable:Fire(Timetable)
	table.remove(TimetableList, 1)
	task.wait(1)
	print(TimetableList[1].." - "..TimetableList[2].." ROUTE NUMBER: "..script.Parent.Parent.RouteNumber.Value)
	if real then
		print("Success")		
	else
		warn("FINISH CHAPA  "..errorMsg)
		script.Parent.Parent.TimetableUniqueID.Value = 0
		local Database = Chapas.GetChapaDataSERVER:Invoke(script.Parent.Parent.Line.Value)
		Database[script.Parent.Parent.ChapaNumber.Value][1] = false
		Database[script.Parent.Parent.ChapaNumber.Value][2] = 0
		Chapas.WriteDataSERVER:Fire(script.Parent.Parent.Line.Value, Database)
		script.Parent.Parent.isInRoute.Value = false
	end
end)

Here is the protected function along with the variables (ABOVE the section showed before, all inside the same script) (please ignore the silly names :smile:) :

local TimetableList = {}
local nextEvent = script.Parent.Parent.NextTimetable
local Chapas = workspace.ChapaDatabase
local real, errorMsg = pcall(function()
	local Timetable = {}
	Timetable = workspace.Timetables.GetTimetableSERVER:Invoke()
	print(TimetableList)
	repeat
		print("Waiting...")
		--print(Timetable[TimetableList[1]][1])
		print(TimetableList[1])
		task.wait(1)
	until script.Parent.Parent.RouteNumber.Value == Timetable[TimetableList[1]][1] 
	if script.Parent.Parent.isInRoute == true then
		script.Parent.Parent.TimetableUniqueID.Value = TimetableList[1]
		Timetable[script.Parent.Parent.TimetableUniqueID.Value][4] = true
		workspace.Timetables.WriteToTimetable:Fire(Timetable)
	end
end)

The area that gives out the error is in the “until”. It returns this error:

The area that is giving out the error basically compares the first value of a Timetable inside an array that is returned when Invoking the Script that stores them. Because other elements of my system do the same thing, I know for sure it correctly gets the Timetable.

For reference, this is an example of an array element for each Timetable:

	{"R00701", 7, 2, false, 0, 0, {"00:00" , nil, nil, nil, nil, nil, nil, nil, nil, nil}},

The issue is that while there are Timetables still existing, it gives out an error so it thinks there are no more Timetables left In this case you can see that “Timetable List” had 3 values and then one of them got removed (those values were manually added in the system for testing reasons). So the issue of the Array being empty is out the table. Then I checked if the Value was “nil”, which, from the picture, it’s not.

After trying many different fixes I am still facing this problem. I hope I gave all the necessary info. If there is anything I can provide more about the issue feel free to ask! Thanks a lot in Advance! :smiley:

1 Like

I’m not sure exactly which line is erroring since we don’t have line numbers in your post, but I suspect it would be down to these lines.

The error you’re seeing says you’re attempting to index nil with a number, for example (nil)[1] which obviously would not work because nil is not a table. But why is it nil? That’s what you need to track down.

If Database[script.Parent.Parent.ChapaNumber.Value] returns nil, that is there is no entry for that particular ChapaNumber in the database, then the next index [1] or [2] will be attempting to index nil. Take a look at that database value and make sure it contains an entry for that ChapaNumber.

edit: Sorry, I didn’t read carefully enough the first time to see that the source of this warning is coming from the second snippet you posted. So the debug process then is to figure out where you’re indexing something with a number within your pcall’d function. I see a few places, but it’s likely the first one that’s causing the problem

This line could result in this error in three ways:

  • If TimetableList is nil
  • If TimetableList[1] is a number and Timetable is nil
  • If Timetable[TimetableList[1]] is nil
2 Likes

Sorry for not mentioning, but that part of the script is related to another procedure of the system. The area that is giving out the problem is this line (inside the protected function, hence the output being orange)

	until script.Parent.Parent.RouteNumber.Value == Timetable[TimetableList[1]][1]

it is trying to Index nil to what I suspect being TimetableList[1], but there is where the issue gets weird. TimetableList[1] is a number that corresponds to the exact “UniqueID” in that Table, and as you could see from the output TimetableList[1] EXISTS and is the number 4.

Hope this info helps

1 Like

Since TimetableList[1] is confirmed to exist as the number 4, that means there are two remaining error possibilities.

  • If TimetableList is nil
  • If Timetable is nil
  • If Timetable[4] is nil

You can either print out these values to figure out what’s going on, or add a breakpoint to this line to pause the script when it runs and check the values yourself.

2 Likes

After taking into account the possibilities you pointed out I decided to check them.

As you can see. Inside the Timetable that it is retrieving the value exists.

3 Likes

I think I see what’s going on here.

The pcall executes the function right away, and at that point, TimetableList is still just an empty table, so TimetableList[1] is nil and therefore Timetable[TimetableList[1]][1] becomes Timetable[nil][1] which becomes (nil)[1] which results in the error about indexing nil with a number.

Once this errors, it exits the pcall and stores the error in the errorMsg variable.

After all that happens, then the rest of your code runs when the nextEvent event fires, where it populates TimetableList and then it prints the value of TimetableList[1], which exists now that it’s been populated.

nextEvent.Event:Connect(function()
	local Timetable = {}
	Timetable = workspace.Timetables.GetTimetableSERVER:Invoke()
	Timetable[script.Parent.Parent.TimetableUniqueID.Value][4] = false
	workspace.Timetables.WriteToTimetable:Fire(Timetable)
	table.remove(TimetableList, 1)
	task.wait(1)
	-- All this code in this event connection, including populating and printing, is happening
	-- AFTER it was already meant to be used inside of the pcall() above
	print(TimetableList[1].." - "..TimetableList[2].." ROUTE NUMBER: "..script.Parent.Parent.RouteNumber.Value)

Can you confirm that the output you’re seeing from inside that pcall function probably says Waiting... but prints a blank line where you would expect to see the value of TimetableList[1]?

	repeat
		print("Waiting...")
		--print(Timetable[TimetableList[1]][1])
		print(TimetableList[1]) -- Are you seeing this value actually get printed?
		task.wait(1)
2 Likes

I tested an it appears that not even “Waiting…” is appearing in my output. It goes from the last print in the connection directly to the error.

1 Like

I recommend adding a breakpoint and stepping through it line by line to figure out what is happening.

Not reading all of this, but make sure you are indexing correctly. Spam prints and/or breakpoints, really hard to solve your problem with unclear context and incomplete snippets. Also fyi: tables passed to bindables are copied and not the original table.

--!strict

local bindableFunction: BindableFunction = Instance.new("BindableFunction")
local bindableEvent: BindableEvent = Instance.new("BindableEvent")

bindableFunction.OnInvoke = function(...: any): ()
	print(...)
end

bindableEvent.Event:Connect(function(...: any): ()
	print(...)
end)

local t = {}

print(t) -- table: 0xd6a5a40802490f4b  {}
bindableFunction:Invoke(t) -- table: 0x6f6ff92a7752613b  {}
bindableEvent:Fire(t) -- table: 0x530340e1e9abf78b  {}

Quite unexpected the outcome of my testing. I think I might know the cause of it now. I observed that it tried to execute the pcall right from the beginning, which will get an empty table, as you would need to assign a “Chapa” to get the values there. Will get back once I got it sorted.

imagem

With that I figured out a way to fix it. I really didn’t expect them to start right away. My fix was simply to put the pcall inside the connection function to the event trigger. Thanks a lot for the heads up about pcalls.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.