ktoxktox docs
ktx_garages

Problems

The errors that only happen with garages.

Install, framework and database errors are under Problems in Setup.

The garage stays empty although the rows are in the table

A column name. The preset for your framework is not what your server uses, most often because the vehicle table was renamed or a column added by another script. See Database.

Vehicles disappear when stored

The same cause, from the other side. The row is written with a column the read does not use. Both take their names from the same block, so hold Config.Database against the columns your vehicle table really has. See Database.

The builder command does nothing

Config.Builder.allow does not match. Aces and groups both work, one match is enough. Test with an empty list, and if it opens then, the entry is the problem and not the command.

A co-owner cannot enter

Config.CoOwnership.requireOwnerPresent is on and the owner is not online. That is what the setting does, see Ownership.

Vehicles are gone after a restart

On QBox this is almost always qbx:enableVehiclePersistence. The convar is off in a stock install, and with it off persistence stays off here too, even with Config.PersistVehicles on, because qbx_core does not track the vehicles without it. Set the convar and persistence follows.

On ESX and qb-core it is Config.PersistVehicles itself. On ox_core the setting is not read at all, persistence is always on and belongs to ox_core.

What was out and does not come back ends in the impound, but only where the restart sweep runs, and it stays out while Config.PersistVehicles is on. See Impound.

A vehicle that was outside is in no garage and in no impound

QBox with the settings as they ship. Config.PersistVehicles is on, so the restart sweep steps aside and touches nothing. qbx:enableVehiclePersistence is off in a stock install, so qbx_core never tracked the vehicle and does not put it back either. The row keeps state = 0, which reads as out in the world, and nothing is out there. A garage lists rows on 1, the impound shows what stands in its own table, so the vehicle is in neither.

parkLooseVehicles does not reach it. That export looks for vehicles that count as stored and name no garage, and this one counts as taken out.

One way out, and the order decides whether it works. The sweep is the only thing that reaches these rows, and it runs only when nothing else is set to bring the vehicles back: Config.PersistVehicles off, and the two convars not standing on true and full together. So the recovery restart comes first and the handover to qbx_core after it.

Set Config.PersistVehicles = false, put qbx:enableVehiclePersistence and qbx:vehiclePersistenceType back to the values they ship with, leave Config.Impound.enabled on, and restart with nobody on the server. The sweep then takes every row on 0 that carries a garage of this resource or none at all and gives it a place, the last garage first if Config.Impound.tryGarageFirst is on, the impound otherwise. Rows naming a garage from another script are counted in a console line and left where they are. The empty server matters: with Config.PersistVehicles off nothing that leaves a garage is handed to qbx_core, so a vehicle driven out during that session strands the same way at the next restart.

Then set qbx:enableVehiclePersistence to true, qbx:vehiclePersistenceType to full and Config.PersistVehicles back to true, and restart again. The three belong together: the setting decides whether a vehicle leaving a garage is registered with qbx_core at all, the convars decide whether qbx_core puts it back. From that restart the sweep stays out of the way, which is what you want while all three are set.

The type filter lets everything through

The types on the garage are empty and the mode is still none. The mode has to be set to whitelist or blacklist in the builder, ticking groups alone does nothing.

Two players stand in the same garage and see different cars

That is the routing bucket doing its job. Only the owner, a co-owner, an invited guest and colleagues in a job garage share an instance. Everybody else gets their own.