Debugging FiveM resources
Find and fix bugs in FiveM scripts: read SCRIPT ERROR lines, print and dump tables, the F8 and server consoles, NUI devtools, common Lua errors and a debugging routine.
Эта документация пока на английском.
Most FiveM bugs are found in minutes if you know where to look. This page is the routine: where errors show up, how to read them, how to narrow down a bug, and the errors you’ll see most.
Where output goes
| Output from | Shows in |
|---|---|
Server scripts (print, errors) |
The server console / txAdmin Live Console, and txAdmin’s log files |
| Client scripts | The F8 console in game, and CitizenFX.log in the FiveM application data logs folder |
| NUI JavaScript | NUI DevTools (nui_devtools in F8) |
| Resource start/stop messages | Server console |
Keep the F8 console and the Live Console open side by side while you test.
Reading a script error
SCRIPT ERROR: @my_shop/server/main.lua:42: attempt to perform arithmetic on a nil value (local 'price')
> handler (@my_shop/server/main.lua:42)
> fn (@ox_lib/imports/callback/server.lua:28)@my_shop/server/main.lua:42: resource, file, line. Go there first.attempt to perform arithmetic on a nil value (local 'price'): what went wrong and which variable.priceisnilon line 42.- The lines starting with
>are the stack trace: how the code got there. Here an ox_lib callback called our handler.
Now ask: why is price nil? Usually a table lookup with a key that doesn’t exist (Config.Prices[item] with a typo in item), or an argument the other side didn’t send.
Print debugging
Plain print is still the most used tool:
print('buy called', src, item, amount)
print(json.encode(data, { indent = true })) -- dump a tablejson.encodeturns tables into readable text.print(someTable)alone prints onlytable: 0x....- ox_lib has
lib.print.info(...),lib.print.debug(...)with log levels you can switch with a convar (ox:printlevel). - Prefix your prints with the resource or function name so you can find them among other output.
- Remove debug prints (or put them behind a
Config.Debugflag) before release. Spamming the console costs performance.
A debugging routine
- Reproduce it. Find the exact steps that trigger the bug.
- Read the first error, not the last. Later errors are often side effects.
- Check which side the problem is on: does the server get the event? Put a print at the top of the server handler. Does the client get the reply? Print in the client handler.
- Check the inputs: print the arguments at the start of the function. Half of all bugs are “the value wasn’t what I thought”.
- Cut it in half: comment out half of the suspicious code, see if the bug stays, repeat.
- Restart just your resource (
ensure name) instead of the whole server, it’s faster. But if things behave oddly after many restarts, restart the server: some resources don’t clean up on stop. - Check the load order: framework not started yet, dependency missing,
ensureorder inserver.cfg. - Change one thing at a time, then test.
The errors you’ll see most
| Error | Usually means |
|---|---|
attempt to index a nil value (global 'QBCore') / 'ESX' / 'lib' |
You never got the framework or library object in this file or resource. Add local QBCore = exports['qb-core']:GetCoreObject(), shared_script '@ox_lib/init.lua', or @es_extended/imports.lua. |
attempt to index a nil value (local 'Player') |
GetPlayer(source) returned nil: wrong source (used after a Wait), player not loaded yet, or the player left. Check before using. |
attempt to call a nil value (field 'X') |
Calling a function that doesn’t exist: typo, wrong framework version, or a method renamed in an update. |
No such export X in resource Y |
Resource not started, wrong name, wrong side, or the export doesn’t exist in that version. |
attempt to compare number with nil |
A value you compare is missing. Often a config key typo. |
bad argument #1 to 'X' |
Wrong type passed to a function or native (a string where a number is expected, a nil). |
Couldn't load resource X |
Manifest syntax error or missing file. |
SCRIPT ERROR ... stack overflow |
A function calls itself forever, or two events trigger each other. |
json.decode error |
The string isn’t valid JSON, often an HTML error page from PerformHttpRequest. |
| Nothing happens, no error | The event isn’t registered as a net event, the handler name has a typo, or the code never runs. Add a print at the entry point. |
Client debugging tools
- F8 console commands:
resmon 1(resource CPU and memory),netgraph(network graph),cl_drawfps true,profiler record(see Threads and performance). nui_devtools: Chrome DevTools for NUI. Your JavaScript errors andconsole.logappear there.- Draw it: draw a marker or text at the coordinates your code uses, to see where it thinks things are.
- Coordinates: print
GetEntityCoords(PlayerPedId())andGetEntityHeading(PlayerPedId())to grab positions for configs, or pick them on the Interactive Map.
Server debugging tools
- The txAdmin Live Console with search, and the log files in
txData. statuslists players and their IDs.mysql_debugandmysql_slow_query_warningconvars for oxmysql.- The server profiler (
profiler record 500in the server console, thenprofiler saveJSON file.json) for slow ticks. Drop the file into the Profiler Analyzer to see which resources use the most time. - txAdmin’s performance chart for hitches over time.
Debugging streamed assets
- Missing model or texture: check the file is in
stream/, the name matches exactly (case matters on Linux), and the resource is started. The Vehicle Pack Validator checks a vehicle resource for broken links between metas, stream files and the manifest. - A
data_filepath that doesn’t match a file listed infilesis silently ignored. - Oversized asset warnings in the server console point to textures that need shrinking.
More in Streaming custom assets.
Tools that make debugging easier
- The Lua Language Server in VS Code flags undefined globals and wrong argument counts before you run the code. See Start developing.
- Git:
git diffshows exactly what changed since it last worked.git stashlets you test the old version in seconds.
Asking for help
When you’re stuck, a good question gets an answer fast:
- What you’re trying to do, in one sentence.
- The exact error text (copied, not a phone photo of the screen).
- The relevant code, formatted, with line numbers matching the error.
- What you already tried.
- Artifact build, framework and version.
Post it on forum.cfx.re in the Development category or in the framework’s Discord support channel.
Next: Streaming custom assets.
