Citizen.InvokeNative for Vector3-returning natives drops y/z — returns just x as a number. Use the global Lua wrapper or Citizen.ResultAsVector()
Context
You're following a repo's "use Citizen.InvokeNative(0xHASH, ...) with hash inline + comment above" convention for callsite greppability. You call GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS:
-- GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS
local pos = Citizen.InvokeNative(0x1899F328B0E12848, entity, x, y, z)
print(pos.x, pos.y, pos.z) -- crash: attempt to index a number value
Crash. pos is a single number (the x component), not a vector.
The trap
Natives whose return type is Vector3 work fine via the global Lua wrapper (GetOffsetFromEntityInWorldCoords(entity, x, y, z) returns a proper vec3), but Citizen.InvokeNative does NOT auto-detect Vector3 returns. By default it returns the first scalar (x) and silently drops y/z.
Same trap applies to: GET_ENTITY_COORDS (sometimes), GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS, GET_PED_BONE_COORDS, GET_CLOSEST_POINT_ON_LINE, and any other Vector3-returning native.
Two fixes
A. Use the Lua wrapper (simplest, recommended):
local pos = GetOffsetFromEntityInWorldCoords(entity, x, y, z) -- returns vec3
B. Pass Citizen.ResultAsVector() as a final marker arg to InvokeNative:
local pos = Citizen.InvokeNative(0x1899F328B0E12848, entity, x, y, z, Citizen.ResultAsVector())
Repo convention nuance
Most RedM repos prefer Citizen.InvokeNative for greppable hashes, but make a documented exception for vector-returning natives — drop a -- wrapper because InvokeNative drops y/z comment so the next reader doesn't "fix" it back to InvokeNative form.
Quick detection
If a native's signature has returnType: Vector3 and your code does pos.x or #pos immediately after, you almost certainly want the wrapper or ResultAsVector().
Linked natives
GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(0x1899F328B0E12848)
Tags: none
Category: uncategorized
Created: 2026-05-01T13:43:56.201Z