Script tells me to attempt to index nil with color even tho it just a second ago used it just fine

hi, so basically I have this little control room alarm script right, and
On Code 1 we can see it using Directory.WhiteTrigger.KeyCardReader1.KeyCardReader:FindFirstChild(“Light”).Color that works perfectly just fine in this part of code, however SOMEHOW in the function which is called out in this script Code2 “Initiate Cooldown” it dropps me an error Workspace._TRIGGERS.ControlRoom.Handler:36: attempt to index nil with 'Color'

Can someone tell me how is that possible? First it works in Code 1 and after that in the same script it refuses to work with the same parts it? I don’t get it

Code 1

function TriggerWhite(player)
	KeycardAccess = Directory.WhiteTrigger.KeycardAccess
	local KeycardRank = CheckKeycard(player)
	if KeycardRank ~= nil and KeycardAccess:FindFirstChild(KeycardRank).Value then
		DisableCodes()
		Directory.WhiteTrigger.KeyCardReader1.KeyCardReader:FindFirstChild("Light").Color = COLOR_SCHEME.Success
		warn("//CR: PROTOCOL ACTIVATED - CODE WHITE")
		NotifyEvent:FireAllClients( 1,"SITE STATUS UPDATED", "CURRENT SECURITY PROTOCOL \n \n CODE WHITE")
		SecurityCode.Value = "CODE WHITE"
		Directory.WhiteTrigger.KeyCardReader1.KeyCardReader:FindFirstChild("Light").Color = COLOR_SCHEME.Success
		for _, model in pairs(Spakers:GetChildren()) do
			for _, part in pairs(model:GetChildren()) do
				for _, sound in pairs(part:GetChildren()) do
					if sound:IsA("Sound") and sound.Name == "AnnounceSound" then
						sound.SoundId = WHITE_SFX_V
						sound:Play()
					elseif sound:IsA("Sound") and sound.Name == "AlarmSound" then
						sound:Stop()
					end
				end
			end
		end
		InitiateCooldown()
		EnableCodes()
	else
		-- Keycard access denied
		print("Access denied. Insufficient keycard level.")
		Directory.WhiteTrigger.KeyCardReader1.KeyCardReader:FindFirstChild("Light").Color = COLOR_SCHEME.Failed
		wait(5)
		Directory.WhiteTrigger.KeyCardReader1.KeyCardReader:FindFirstChild("Light").Color = COLOR_SCHEME.Default
	end
end

Code2

function InitiateCooldown()
	print("Site Protocol Cooldown started")
	for CooldoolDown = 30, 0, -1 do
		print("SSC:\\ "..CooldoolDown)
		Directory.WhiteTrigger.KeyCardReader1.KeyCardReader:FindFirstChild("Light").Color = COLOR_SCHEME.Reboot
		Directory.YellowTrigger.KeyCardReader1.KeyCardReader:FindFirstChild("Light").Color = COLOR_SCHEME.Reboot
		Directory.RedTrigger.KeyCardReader1.KeyCardReader:FindFirstChild("Light").Color = COLOR_SCHEME.Reboot
		Directory.BlackTrigger.KeyCardReader1.KeyCardReader:FindFirstChild("Light").Color = COLOR_SCHEME.Reboot
		Directory.OrangeTrigger.KeyCardReader1.KeyCardReader:FindFirstChild("Light").Color = COLOR_SCHEME.Reboot
		Directory.PurpleTrigger.KeyCardReader1.KeyCardReader:FindFirstChild("Light").Color = COLOR_SCHEME.Reboot
		wait(1)
		Directory.WhiteTrigger.KeyCardReader1.KeyCardReader:FindFirstChild("Light").Color = COLOR_SCHEME.Default
		Directory.YellowTrigger.KeyCardReader1.KeyCardReader:FindFirstChild("Light").Color = COLOR_SCHEME.Default
		Directory.RedTrigger.KeyCardReader1.KeyCardReader:FindFirstChild("Light").Color = COLOR_SCHEME.Default
		Directory.BlackTrigger.KeyCardReader1.KeyCardReader:FindFirstChild("Light").Color = COLOR_SCHEME.Default
		Directory.OrangeTrigger.KeyCardReader1.KeyCardReader:FindFirstChild("Light").Color = COLOR_SCHEME.Default
		Directory.PurpleTrigger.KeyCardReader1.KeyCardReader:FindFirstChild("Light").Color = COLOR_SCHEME.Default
		wait(1)
	end
	wait(1)
	return
end```

I cannot stress enough how much of a bad idea it is to do something like this.
image

Please read this thread to understand why, specifically bad habits #2 and #3:

Essentially, if for whatever reason the instance “Light” isn’t available, the script will error because :FindFirstChild("Light") will evalulate to nil and then you try to index nil with .Color. You did nothing to handle the scenario for when it is nil and just assumed that “Light” always exists.
Now “Light” can be missing because it was destroyed by another script, or, more likely, because it hasn’t loaded in yet and the script ran before everything has replicated to the client. So it tries to look for an instance that doesn’t exist and just gives you nil when it can’t find it.

Just a second ago the script Found the instance light and changed it color, and then when it moves to cooldown function which has the same line of code Directory.WhiteTrigger.KeyCardReader1.KeyCardReader:FindFirstChild("Light").Color
it decides that it no longer exists even if it does, i checked it from server side.
So the question is why. Also I will read the article you send about bad practices once I have a while.

Well, switching to wait for child was not efficient as apparently it does not exist *reminder it literally just changed the color before to green and back to white to confirm that you made an interaction.
image

1 Like

Alright, Apparently I found the solution to this as I must have accidentally renamed one of the parts to Q isntead of Light. Happens I guess and thank you linking the thread it helped a lot as well!

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