[script:fivetrace] error tracking for FiveM resources
[script:my-awesome-script] server/main.lua:142 · 9 servers · 1,284 times today
^1SCRIPT ERROR^7: your script is breaking on servers you cannot see
You sell a script. It runs on other people’s machines. When it throws, the error scrolls past in a console you will never open — and you hear about it in a Discord message, days later, with no stack trace and a refund attached.
what you get instead
attempt to index a nil value (field 'inventory')
my-awesome-script · server/main.lua:142
1,284 today · 9 servers · first seen 3 days ago · new in 1.4.3
1,284 lines, one row. Grouped by what broke rather than by when it happened.
Create a script
Name it, take the DSN. That key can submit errors and read nothing, so it ships safely inside the resource you sell.
Load the SDK into your resource
Into it, not beside it. That distinction is the whole trick, and the next section explains why.
shared_script '@fivetrace-sdk/init.lua' dependency 'fivetrace-sdk'
Initialise once
Every unhandled error in your threads, timers and handlers is now captured, batched and sent. Nothing else to wire.
FiveTrace.init({ dsn = 'ft_...' })FiveM gives every resource its own isolated Lua state. A tracker sitting in a separate resource cannot see into yours. It will boot, print that it is running, and report nothing, forever.
So the SDK is a file your resource loads, not a resource that watches from outside. It wraps your threads, timers and handlers from within — which is also the only reason it can hand you a stack instead of a shrug.
| message | attempt to index a nil value (field ‘inventory’) |
| file:line | server/main.lua:142 |
| stack | giveItem → handlePurchase → [global chunk] |
| resource | my-awesome-script |
| version | 1.4.2 |
| server | from convars, if the operator set one |
| player data | no such field exists |
A real multi-frame stack, read while the erroring frames are still live. You land on the function, not a sentence.
The same bug from four hundred servers is one issue with a count. Messages are normalised before they are fingerprinted.
New issue: one ping. Came back after you fixed it: one ping. Spike: one ping, then quiet for half an hour. A broken loop does not produce four hundred messages overnight.
Every issue says which of your releases it has been seen on, read from your fxmanifest. Ship a fix and it says last seen on 1.4.2 once 1.4.3 is reporting everything else — and an issue only ever seen on your newest release is marked new in 1.4.3, because you shipped it.
Batched on its own thread, thirty a minute per resource, dropped silently when we are unreachable. It never blocks your server.
The payload has no field for an identifier, a licence or an IP. Nothing to trust us about — there is nowhere to put them.
Issues never age out, so a script that has been selling for a year has more than one screen holds. Search the message, the file or the resource, and the tab you were on survives it.
One script, dozens of servers, one page. Every issue says how many of them it is hitting, which is the part that tells you where to look: three of four is your bug, three of four hundred is three broken configs.
[#money] the other product · for server owners
If you run a server rather than sell a script, the thing you cannot do today is search your logs. Live logs take the same SDK, a key of your own, and give your staff something Discord cannot: an answer about last Tuesday.
live logs →[script:fivetrace] alert sent · issue resolved · 0 servers affected