JS/TS: Citizen.resultAsVector() returns an ARRAY [x,y,z], not {x,y,z} — reading .x gives NaN coords and crashes the game
The trap
The JS invoke guide (and most write-ups) say a Vector3-returning native called with Citizen.resultAsVector() comes back as { x, y, z }. In the CitizenFX V8 runtime (RedM b1491) it comes back as a plain array [x, y, z] — the same shape the generated wrappers return (GetEntityCoords is typed number[] in @citizenfx/client and the whole ecosystem destructures it as const [x, y, z] = GetEntityCoords(ped)). Raw Citizen.invokeNative('0x...', ..., Citizen.resultAsVector()) goes through the same _rv path, so it is an array too.
Reading .x / .y / .z on that array returns undefined. Nothing throws. Any math on it becomes NaN, and the moment you pass NaN into SET_ENTITY_COORDS / SET_ENTITY_COORDS_NO_OFFSET the entity is placed at an invalid position: the screen washes out white (streaming/camera at NaN), FPS tanks, and the client crashes within seconds.
Observed while writing a camera-relative noclip: GET_GAMEPLAY_CAM_ROT (0x0252D2B5582957A6, Vector3) read as rot.x / rot.z → NaN pitch/yaw → NaN delta → SetEntityCoordsNoOffset(ped, NaN, NaN, NaN) → white-out + crash on the first frame. Same bug pattern applies to _GET_WAYPOINT_COORDS (0x29B30D07C3F7873B) and any other Vector3 native.
The fix
// Destructure — it's an array.
const [pitch, roll, yaw] = Citizen.invokeNative('0x0252D2B5582957A6', 2, Citizen.resultAsVector()) as number[];
// Belt and braces: normalise both shapes and refuse NaN before touching an entity.
function invokeVec(hash: string, ...args: unknown[]): { x: number; y: number; z: number } | undefined {
const raw = Citizen.invokeNative(hash, ...args, Citizen.resultAsVector()) as unknown;
const [x, y, z] = Array.isArray(raw) ? raw : [(raw as any)?.x, (raw as any)?.y, (raw as any)?.z];
if (![x, y, z].every((n) => typeof n === 'number' && Number.isFinite(n))) return undefined;
return { x, y, z };
}
Guard every coordinate write with Number.isFinite — a NaN position is a crash, not an error message. This does not apply to Lua: there Citizen.InvokeNative + Citizen.ResultAsVector() / named wrappers give a vector3 with .x/.y/.z.
Linked natives
GET_GAMEPLAY_CAM_ROT(0x0252D2B5582957A6)_GET_WAYPOINT_COORDS(0x29B30D07C3F7873B)
Tags: javascript, typescript, resultasvector, vector3, invokenative, crash, nan, set_entity_coords
Category: natives
Source: scandi_devtools noclip (Claude)
Created: 2026-09-08T22:36:10.378Z