F5 StudioF5 Studio
Skip to main content

Troubleshooting

Most issues come from one of five sources: boot order, framework/inventory/target detection, admin access mapping, money configuration, or a delivery/target edge case. Work through the relevant section below.

The first thing to do for almost any problem is enable debug and read the server console:

config.lua
F5Cfg.Debug.enabled = true
-- the categories below are on by default; PERF is off

The Market Doesn't Open At All / Resource Is Inert

Symptom: Using the item or running /market does nothing; no UI, sometimes no command at all.

1. Framework / inventory detected?

The bridge runs detection once at startup. With the BRIDGE category on you should see:

[SERVER][BRIDGE] detected framework=qb inventory=qb

If instead you see an inert message, the resource isn't running:

[SERVER][ERROR] [ERR]  [BRIDGE] no supported framework detected (esx/qb/qbx) — resource inert
[SERVER][ERROR] [ERR] [BRIDGE] no supported inventory detected for framework esx

2. Boot order

f5_shadowmarket must start after oxmysql, your framework, and your inventory/target. A reversed order means detection runs before those resources exist.

server.cfg
ensure oxmysql
ensure qb-core
ensure qb-inventory
ensure qb-target
ensure f5_shadowmarket

3. Wrong adapter detected?

If detection picked the wrong inventory (e.g. esx_native while you actually run ox_inventory), force it:

config.lua
F5Cfg.Framework.inventory = 'ox'
F5Cfg.Framework.mode = 'qb' -- only if framework detection is also wrong

See Framework Compatibility.

The Item Isn't Usable

Symptom: Using market_tablet from the inventory does nothing.

1. Item registered?

If the icon is broken or the label shows the raw id, the item isn't registered in your inventory. Re-do Items → Step 2.

2. useable / consume flag

  • QBCore (shared/items.lua): useable = true is required.
  • QBox / ox_inventory: the item just needs to exist; F5 Shadow Market uses consume = 0 (reusable).

3. Boot order

The bridge registers the usable item at startup. If the inventory wasn't up yet, registration is lost — fix the boot order (see above).

4. Command mode

In 'item_only' and 'item_or_command' modes the player must carry the tablet. If you want command access without the item, set F5Cfg.Command.mode = 'command_always'. See Commands.

Inventory Items Have No Images in the Market

Symptom: The "create listing" item grid shows placeholders instead of icons.

1. Icon not copied

Copy your item icons into the inventory's image folder (see Items → Step 1).

2. esx_native has no images

The ESX native inventory adapter does not resolve item images at all. Use a third-party inventory (e.g. ox_inventory) on ESX for icons.

3. tgiann images

tgiann-inventory serves images from a separate inventory_images resource as .webp. Make sure your item images exist there.

4. Override the path

If your inventory uses a non-standard image folder, set an explicit template:

config.lua
F5Cfg.Inventory.imageUrl = 'nui://my-inventory/images/%s.png'

The Item Grid Is Empty (codem on ESX)

Symptom: On ESX with codem-inventory, the create-listing grid is always empty.

This is a known limitation: the codem adapter can only read the player's item list on a QB/QBox base. On ESX it returns nothing. Use a different inventory on ESX, or run codem on QB/QBox. See Framework Compatibility → Known Limitations.

"Access Denied" on /marketadmin

Symptom: An admin can't open the panel.

1. Confirm a path is enabled

Access requires the ACE permission or a framework group. If you set acePermission = '' and frameworkGroups = {}, nobody has access.

2. ACE path

server.cfg
add_ace group.admin f5market.admin allow
add_principal identifier.steam:XXX group.admin

Confirm F5Cfg.Admin.acePermission matches the ACE you granted (default f5market.admin).

3. Framework group path

The default groups are admin and god. The check resolves as:

  • QBCoreQBCore.Functions.HasPermission(src, 'admin') (or ACE group.admin)
  • QBox — ACE group.admin
  • ESXxPlayer.getGroup() == 'admin'

Make sure the player is actually in one of F5Cfg.Admin.frameworkGroups.

4. Catch the rejection

Denials log to the SECURITY category:

[SERVER][SECURITY] [WARN] admin_denied src=12 event=dashboard

That confirms the access check ran and returned false — fix the ACE/group mapping above.

Payouts / Balance Use the Wrong Money

Symptom: The market shows or pays the wrong account.

The market uses a single wallet: F5Cfg.Money.payoutType. If you see a fallback warning at startup:

[SERVER][BRIDGE] [WARN] payoutType "crypto" not active, falling back to bank

…then your payoutType has no account on the active framework (e.g. crypto on ESX, blackmoney on QB/QBox). Set payoutType to an id that exists for your framework — see Framework Compatibility → Money & Currencies.

Package Pickup Doesn't Work

Symptom: The buyer can't collect the dropped package.

1. Target detected?

With F5Cfg.Target.system = 'auto', the bridge uses ox_target, else qb-target, else no target interaction (the buyer collects from the Orders panel). If your target isn't detected, force it:

config.lua
F5Cfg.Target.system = 'ox'   -- or 'qb', or 'none'

2. Distance

The buyer must be within roughly F5Cfg.Delivery.itemPackage.pickupDist (default 2 m) of the package — the target prompt is allowed a small extra margin on top of that.

3. Visibility

With visibility = 'parties' only the buyer and seller see the package. If a third party should see it, set visibility = 'everyone'.

Seller Can't Drop the Package

Symptom: The placement ghost is red and won't confirm.

The package must be placed within F5Cfg.Delivery.maxDropoffDist (default 24 m) of the seller — the placer subtracts F5Cfg.Placer.pedDistMargin (default 0.5 m) as a safety margin. Move closer to the chosen spot, or aim at a clear, unobstructed surface.

Orders Keep Expiring

Symptom: Sales expire and refund before completing.

  • The seller has dropoffTimeoutHours (default 24) to drop off after the sale.
  • The buyer has pickupTimeoutHours (default 24) after dropoff to collect.

Raise these in F5Cfg.Delivery if your players need longer.

Webhooks Not Arriving

Symptom: Market actions happen but nothing reaches Discord.

1. URL set

Either Webhooks.defaultUrl or the event's own url must be non-empty. Both empty → the event is skipped.

2. Event enabled

Confirm Webhooks.events[name].enabled = true.

3. Watch the queue

config.lua
F5Cfg.Debug.enabled            = true
F5Cfg.Debug.categories.WEBHOOK = true

The console shows enqueue / sent / skip lines. A skip with reason=disabled means the event is off; reason=no_url means no URL resolved. A 429 is a rate-limit (honored automatically) — if chronic, raise Webhooks.queue.tickMs. A 4xx (e.g. 404) means the webhook URL is wrong/revoked; generate a new one.

4. admin_audit specifically

Admin actions only log when F5Cfg.Admin.auditWebhook = true.

See Webhooks for the full pipeline.

Database Errors on Startup

Symptom: Tables don't exist, migrations fail, or DB calls throw.

1. SQL driver detected?

The built-in SQL bridge (server/sql_bridge.lua) auto-detects oxmysql, mysql-async or ghmattimysql (in that order, within a 30 s window). With the IO category on you should see:

[SERVER][IO] [sql_bridge] driver detected: oxmysql

If instead you see this, no driver was found in time and every DB call will throw:

[SERVER][ERROR] [ERR]  [sql_bridge] no MySQL driver started within 30000ms (checked: oxmysql / mysql-async / ghmattimysql). f5_shadowmarket DB calls will throw.

2. Using mysql-async / ghmattimysql

The SQL bridge works with any of the three drivers and the manifest declares no hard database dependency, so no manifest edit is needed. Just make sure your chosen DB resource starts before f5_shadowmarket in server.cfg.

3. Schema / privileges

F5Cfg.Database.autoCreateTables (default true) creates and migrates the schema on start. If you set it to false, you must manage the schema yourself. Confirm your DB resource is started before f5_shadowmarket, and that the DB user has CREATE / ALTER privileges. Watch the IO category for query errors.

Still Stuck?

  • Enable F5Cfg.Debug.enabled = true and read the BRIDGE, SECURITY and IO categories.
  • Check the client console (F8) for client-side errors.
  • Open a support ticket on our Discord with: framework + version, inventory + version, target + version, the relevant F5Cfg.* block, and the failing action's console output.

See Also