bad argument #1 to 'X' (number expected, got nil): FiveM Lua исправление

Получаете 'bad argument #1 to X (number expected, got nil)' в FiveM? Как читать номер аргумента и исправить nil сущности, pairs(nil), tonumber и ошибки таблицы.

Где-то в вашей консоли, скрипт останавливается с этим:

text
SCRIPT ERROR: @my_script/client/main.lua:57: bad argument #1 to 'floor' (number expected, got nil)

Функция была вызвана с аргументом, который она не может использовать, и аргумент почти всегда nil. Сообщение говорит вам, какая функция, какой аргумент и какой тип ей требуется. Это руководство показывает, как его читать и обычные источники nil.

Как прочитать сообщение

text
bad argument #1 to 'X' (number expected, got nil)
  • X — это имя функции, которая пожаловалась.
  • #1 — это позиция аргумента: #1 — первый, #2 — второй.
  • number expected — это тип, который требует функция. Это может также сказать string, table или boolean.
  • got nil — это то, что она действительно получила. Это может также быть got table, got string или got no value.

Откройте строку из ошибки и посмотрите на функцию, названную в сообщении. Затем посмотрите на аргумент в той позиции и спросите, откуда она берётся.

lua
local price = Config.Prices[item]
local rounded = math.floor(price)   -- bad argument #1 to 'floor' (number expected, got nil)

Здесь Config.Prices[item] это nil, потому что item не является ключом таблицы. Ошибка находится в строке math.floor, но ошибка в данных.

table expected, got nil

То же сообщение с таблицей появляется с функциями table:

text
bad argument #1 to 'insert' (table expected, got nil)
lua
local list
table.insert(list, 'a')     -- list was never created

Создайте таблицу перед её использованием:

lua
local list = {}
table.insert(list, 'a')

Для таблицы, которая находится в общей структуре, создайте её, когда она отсутствует:

lua
players[source] = players[source] or {}
table.insert(players[source], item)

Перебор nil: pairs и ipairs

В Lua 5.3 и 5.4, которые использует FiveM, перебор nil не удаётся с сообщением, которое называет цикл вместо pairs:

text
bad argument #1 to 'for iterator' (table expected, got nil)
lua
for _, job in pairs(Config.Jobs) do   -- Config.Jobs is nil

Проверьте, где определена таблица: опечатка в имени, файл конфигурации не загруженный манифестом или данные, которые ещё не поступили. Короткий охранник избегает краха, пока вы найдёте реальную причину:

lua
for _, job in pairs(Config.Jobs or {}) do

Используйте это как страховку, а не как исправление. Если Config.Jobs должна существовать, пустой цикл только скрывает ошибку. Связанное сообщение table index is nil охватывает отсутствующие ключи в вложенных таблицах конфиг.

Нативные, которые получают nil

Многие нативные нуждаются в числе, такие как дескриптор сущности. Дескриптор, который nil или 0, обычно означает, что сущность не существует (ещё).

lua
local vehicle = GetVehiclePedIsIn(ped, false)
local plate = GetVehicleNumberPlateText(vehicle)   -- vehicle is 0 when the ped is on foot

Частые источники:

  • Сущность не загружена. Автомобиль, спауненный сервером, недоступен для вашего клиента на мгновение. На клиенте, дождитесь его существования:
lua
local vehicle = NetToVeh(netId)
local timeout = 0
while not DoesEntityExist(vehicle) and timeout < 100 do
    Wait(50)
    vehicle = NetToVeh(netId)
    timeout = timeout + 1
end
  • Функция ничего не вернула. GetPlayerPed(-1), GetClosestVehicle и подобные могут вернуть 0, когда ничего не совпадает. Проверьте значение перед его использованием.
  • Неправильный вектор. Нативный, который хочет три числа, x, y, z, не принимает всю таблицу. Передайте coords.x, coords.y, coords.z или используйте vector3, где нативный берёт один.
  • Отсутствующий ключ в конфиге. Config.Spawn.x это nil когда Config.Spawn написан с [1], [2], [3].

Точный текст зависит от нативного, и некоторые нативные вообще не вызывают ошибку, но ничего не делают. Вот почему охранник стоит добавить:

lua
if vehicle ~= 0 and DoesEntityExist(vehicle) then
    SetVehicleEngineOn(vehicle, true, true, false)
end

tostring, tonumber и string.format

Функции преобразования — это ещё один источник nil:

  • tonumber('abc') возвращает nil, а не ошибку, поэтому краш приходит позже, когда вы используете результат.
  • tostring(value) всегда возвращает строку, даже для nil (это даёт 'nil'), поэтому это безопасно использовать при построении текста.
  • string.format('%d', value) не удаётся когда value это nil: bad argument #2 to 'format' (number expected, got nil).

Когда число поступает от игрока или из команды, проверьте его:

lua
RegisterCommand('pay', function(source, args)
    local amount = tonumber(args[1])
    if not amount then
        return print('Usage: /pay [amount]')
    end
    print(('Paying %d'):format(amount))
end)

Обратите внимание, что args[1] это nil, когда игрок напечатал /pay один, и tonumber(nil) возвращает nil, поэтому проверка выше охватывает оба случая.

Найдите nil

Когда источник не очевиден, выведите значения прямо перед неудачной строкой:

lua
print('item', item, type(item))
print('price', Config.Prices[item], type(Config.Prices[item]))

Затем трассируйте nil обратно к месту, где она должна была быть установлена. Удалите выводы, когда закончите.

Чеклист

Симптом Исправление
bad argument #1 to 'floor' (number expected, got nil) Значение отсутствует: проверьте ключ или переменную, которая её подаёт
bad argument #1 to 'insert' (table expected, got nil) Создайте таблицу в первую очередь: t = t or {}
bad argument #1 to 'for iterator' (table expected, got nil) Таблица, которую вы перебираете, это nil; проверьте её имя и где она заполняется
Нативный не удаётся на сущности Проверьте DoesEntityExist(entity) и дождитесь загрузки сущности
tonumber(...) даёт nil Проверьте ввод игрока перед его использованием
bad argument #2 to 'format' %d и %s требуют реального значения; проверьте аргумент в этой позиции

Если ошибка о чём-то, что является nil вместо плохого аргумента, прочитайте attempt to compare nil и attempt to call a nil value.

Короткие ответы

Что означает 'bad argument #1 to X (number expected, got nil)'?

Функция получила nil в качестве своего первого аргумента, где ей нужно число. X — это функция, #1 — позиция аргумента, а nil — это то, что передал ваш код.

Как исправить 'bad argument #1 to for iterator (table expected, got nil)'?

Вы перебрали переменную, которая nil с помощью pairs или ipairs. Найдите, где эта переменная заполняется и проверьте, она существует, или переберите variable or {}.

Может ли нативное получить nil без ошибки?

В зависимости от нативного, значение nil или недействительное может быть обработано как 0 или просто не делать ничего, поэтому ошибка может скрыться. Проверьте сущность с помощью DoesEntityExist(entity) перед её использованием.

Скрипты без этой проблемы

Advanced BoostingУгон машин на заказ через планшет: контракты от класса D до S+, команды и живая очередь.Смотреть скрипт →CCTV Security CamerasУстанавливаемые камеры, планшет с мультиэкраном в реальном времени и распечатанные фото-улики.Смотреть скрипт →Item Creator V2Создавайте используемые предметы с анимациями, пропами, эффектами и не только — без кода.Смотреть скрипт →

Читайте также