Reading errors and the debugging method
The first time you see a red error you will feel like the program is yelling at you. It is not. An error is a clue, not a verdict. Lua tried to do one specific thing, and one specific part was missing, so it stopped and wrote down exactly what it tried and where. Read in the right order, an error is the most helpful sentence in the whole console. This lesson teaches you to read it calmly, so a broken script becomes a puzzle with the answer already printed, not a wall you bounce off.
Watch
What an error actually is
An error is a message the engine writes when your code asks for something that cannot be done. That is the whole thing. It is not the program insulting you, and it is not a sign you are bad at this. It is a short report with three useful parts in it: the file the problem is in, the line number where it happened, and a plain statement of what went wrong.
Here is one, taken apart:
SCRIPT ERROR: @qu_demo/server.lua:3: attempt to index a nil value (local 'player')Read it left to right and it is almost a sentence. The error came from the resource qu_demo, in the file server.lua, on line 3, and what went wrong is that the code tried to use player as if it held real data, but player was empty. You did not have to guess any of that. The engine handed you the file, the line, and the reason. Your job is just to read it instead of staring past it.
Vocabulary
- error
- A message the engine writes when your code asks for something impossible, then stops that piece of code. It names a file, a line, and what went wrong.
- stack trace
- A list of the calls that led to the error, newest at the top. It answers 'how did we get to the broken line', useful when the error fires far from where the bad value started.
- nil
- Lua's word for 'there is nothing here.' A variable that was never given a value is nil. It only becomes an error when you use the nothing as if it were real data.
- SCRIPT ERROR
- The label FiveM prints in front of an error that came from a resource's Lua code, so you can spot your own bug in a console full of other output.
The five-step method
Almost every error you will ever fix follows the same five moves. The order matters more than anything else here. The single biggest beginner mistake is changing five files before understanding the first error. Do one step, read the proof, then move on.
1. Read the first red line
When code breaks, the console can spill many lines. Read the first one. It is the original cause. The lines below it are usually the stack trace or knock-on noise from the first failure.
2. Open the file it names
The first line names a file, like server.lua. Open that exact file. Not a file that feels related, the one the error printed.
3. Go to the line it names
The error includes a line number, like :3. Go straight to that line. The engine is pointing at the bug. You almost never have to search.
4. Ask what value or function was missing
Read the line and ask one question: what did I assume existed here that was actually empty or wrong. The error usually names it for you, like (local 'player').
5. Fix ONE thing and test
Make a single change. Restart the resource. Run it again. If the error is gone, stop. If a new error appears, you are back at step one with a smaller problem. One change at a time means you always know which change did what.
The four nil errors you will meet
Most beginner errors are the same idea wearing four costumes. nil means "there is nothing here." It turns into an error the moment you use that nothing as if it were real data or a real function. These are the four you will see constantly, with the plain-English meaning of each:
attempt to index a nil value -> you read thing.name on an empty thing
attempt to call a nil value -> you ran thing() but thing is not a function
attempt to concatenate a nil value -> you glued text onto an empty value with ..
attempt to perform arithmetic on nil -> you did math (+ - * /) on an empty valueOnce you recognize these four, you have a head start on a large share of every error you will ever read. They all point at the same question: what value did I assume existed here, and why was it actually empty.
Your fastest tool: print the value
Before you change any code, prove what you are dealing with. The fastest way is to print the value and its type on the line just before the crash:
print(type(player), player)type(player) tells you what kind of thing player is, like table, string, number, or nil. Printing player itself shows you its actual contents. If the console comes back with nil nil, you have your proof: the value really is empty, and now you fix where it should have been filled. This one line answers most nil mysteries in seconds, and it replaces guessing with a fact you can see.
Where to read errors
FiveM runs your code in two places, so errors land in two places. You have to look in the right one or you will swear the error vanished.
Common beginner mistakes
| Symptom | Fix |
|---|---|
You changed five files before understanding the first error. | Stop. Undo the scattered changes. Read the first red line, fix exactly one thing, restart, and test. One change at a time is the only way to know which change mattered. |
You read the last line of the error instead of the first. | The first red line is the original cause. The lines under it are usually the stack trace or follow-on noise. Always start your reading at the top. |
You ignored the file path and fixed the wrong side. | The path tells you which file and which side the bug is on, like server.lua or client.lua. Read it before editing, or you will spend an hour fixing code that was never the problem. |
You see a SCRIPT ERROR with several lines. Which line do you read first?
The first red line, the one at the top. That line is the original cause, and it names the file, the line number, and what went wrong. The lines below it are almost always the stack trace or knock-on errors that the first failure set off. Beginners read the bottom line, panic, and fix the wrong thing. Read the top line, jump to the file and line it names, and you are already most of the way to the fix.
Try it yourself
What you can do now
- Explain that an error is a clue, not a verdict: it names a file, a line, and what went wrong.
- Run the five-step method: read the first red line, open the file it names, go to the line, ask what was missing, fix one thing and test.
- Tell the four nil errors apart: index, call, concatenate, and arithmetic on a nil value.
- Use print(type(x), x) to prove what a value actually is before you change any code.
- Know that server code prints errors to the server console (txAdmin Live Console) and client code prints to F8, and check the right one first.
You can now read an error instead of fearing it, which is the habit every developer leans on for the rest of their life. Next, in "Dependencies and load order", you will see why a script can be perfectly written and still fail, simply because the thing it needs was not started yet.