I am making a tycoon game and in my script, I implemented this if statement
if Data.Tycoon.Floors[Floor.Name].Buttons[Button.Name].ID ~= Button.Name then
The output said: 19:15:06.753 Workspace.Tycoons.Plots.Template.Objects.Buttons.Button Executor:20: attempt to index nil with 'ID' - Server - Button Executor:20
The script returned that the value was nil (I believe so), so I tried another way to execute this code:
if Data.Tycoon.Floors[Floor.Name].Buttons[Button.Name].ID == nil or Data.Tycoon.Floors[Floor.Name].Buttons[Button.Name].ID ~= Button.Name then
This is nerve-racking, I wrote that if the script returns nil, then the piece of line underneath it will execute, but instead it gave me again the same error output, when I literally just said that the code will continue if it returns nil! I’ve been working on this issue for hours and I couldn’t find a single solution. Even my friend of mine was experiencing the same issue! Please, if anyone in this community knows the answer, I’d love you to tell me . Many thanks for considering my request.
Note: Data.Tycoon.Floors[Floor.Name].Buttons[Button.Name].ID is a table, not an instance
You are not allowed to instance non existent Instances in Luau. The provided approach only works for tables and not for Instances. You can use :FindFirstChild() instead to get a nil value if a child with the provided name does not exist.
Data.Tycoon.Floors[Floor.Name].Buttons[Button.Name].ID == nil or Data.Tycoon.Floors[Floor.Name].Buttons[Button.Name].ID ~= Button.Name then
to
Data.Tycoon.Floors[Floor.Name].Buttons[Button.Name] == nil or Data.Tycoon.Floors[Floor.Name].Buttons[Button.Name].ID == nil or Data.Tycoon.Floors[Floor.Name].Buttons[Button.Name].ID ~= Button.Name then
The issue is not that .ID is nil, the issue lies with Data.Tycoon.Floors[Floor.Name].Buttons[Button.Name]. Taking a closer look at the error message Luau is saying that you’re attempting to index the datatype nil with .ID.
To index something is to use the dot operator. An index operation allows you to read keys of tables and members (properties/children/functions) of instances. The error “attempt to index nil with x” is commonly mistaken as “x” being a non-existent key of the indexed table or member of the indexed instance; however, it is not “x” which is non-existent, but what precedes it that is. This means that the following code results in that error:
nil.x
It holds up that we’re using the dot operator on nil, which is described by “attempt to index nil”.
Why
Your error states that you indexed nil with “ID”, so the task that befalls you now is to locate where in your code do you proceed the dot operator with “ID”. That is with the following piece of code:
Buttons[Button.Name].ID
This suggests that the preceding code is resulting in nil:
Buttons[Button.Name]
The above code is, in it of itself, another index operation. You’re attempting to find a key in the dictionary Data.Tycoon.Floors[Floor.Name].Buttons that matches the name of the given button. No key by that button’s name could be found, however, so nil became of that index operation. This means one of two things:
Where a button was expected, it was not found. This is a problem in its own right and requires further investigation.
Out of the buttons traversed, only some are supposed to yield results. If this is the case, your code needs to account for the buttons that do not belong.
What to do
@randomlletters and @DataSigh both provided solutions geared towards scenario #2. To summarize, they’re ensuring that the index operation Buttons[Button.Name] yields a result before attempting to interact with it. Putting that into a more intuitive form helps shed some light:
local button = Data.Tycoon.Floors[Floor.Name].Buttons[Button.Name]
if button then
-- A button exists, now we can read its ID
end
How exactly they compress this assertion into a one-line conditional is reliant on the behaviour of logical operators