Es Extended Error

Hi, I am having an error (Posted below) and it is causing my civilians to not be able to create characters.

Here’s the code. table.insert(tasks2, function(cb2)

        MySQL.Async.fetchAll('SELECT job, job_grade, loadout, position FROM users WHERE identifier = @identifier', {

            ['@identifier'] = player.getIdentifier()

        }, function(result)

            local job, grade = result[1].job, tostring(result[1].job_grade) -- Line 110

            if ESX.DoesJobExist(job, grade) then

                local jobObject, gradeObject = CL.Jobs[job], CL.Jobs[job].grades[grade]

                userData.job = {}

                userData.job.id    = jobObject.id

                userData.job.name  = jobObject.name

                userData.job.label = jobObject.label

                userData.job.grade        = tonumber(grade)

                userData.job.grade_name   = gradeObject.name

                userData.job.grade_label  = gradeObject.label

                userData.job.grade_salary = gradeObject.salary

                userData.job.skin_male    = {}

                userData.job.skin_female  = {}

Help would be appreciated.

Which line is the line 110 from main.lua ?

This one

This is because you haven’t get any result from the query above for the specified player.

That is the correct answer.

The result is nil because it is not finding an entry in the database users table, for that player identifier. Ensure that player.getIdentifier() is the correct function and it’s not xPlayer.getIdentifier() or similar, based on your framework.

I can see that the error mentions “_extended” which I imagine is es_extended, so ESX. In that case, you most likely need to use xPlayer.getIdentifier() providing you have something like local xPlayer = ESX.GetPlayerFromId(source) above this SQL query function. Or you can change player.getIdentifier() to GetPlayerIdentifier(source, 1).

Hope we were able to help you! If this is fixed, please mark it as solved. Thanks! :spades:

1 Like

Changing it to “GetPlayerIdentifier(source, 1)” caused it to give this message

MySQL.Async.fetchAll(‘SELECT job, job_grade, loadout, position FROM users WHERE identifier = @identifier’, {

            ['@identifier'] = GetPlayerIdentifier(source, 1)

causes the issue

Can you please provide the entire function?
Or replace “source” with whatever your player’s server ID is called.
It seems that “source” is not the player’s server ID, so I am wondering what it is, in your script.

table.insert(tasks, function(cb)

    local tasks2 = {}

    -- Get job name, grade and coords

    table.insert(tasks2, function(cb2)

        MySQL.Async.fetchAll('SELECT job, job_grade, loadout, position FROM users WHERE identifier = @identifier', {

            ['@identifier'] = GetPlayerIdentifier(source, 1) -- CHANGED THIS

        }, function(result)

            local job, grade = result[1].job, tostring(result[1].job_grade) -- LINE 110

            if ESX.DoesJobExist(job, grade) then

                local jobObject, gradeObject = ESX.Jobs[job], ESX.Jobs[job].grades[grade]

                userData.job = {}

                userData.job.id    = jobObject.id

                userData.job.name  = jobObject.name

                userData.job.label = jobObject.label

                userData.job.grade        = tonumber(grade)

                userData.job.grade_name   = gradeObject.name

                userData.job.grade_label  = gradeObject.label

                userData.job.grade_salary = gradeObject.salary

                userData.job.skin_male    = {}

                userData.job.skin_female  = {}

                if gradeObject.skin_male then

                    userData.job.skin_male = json.decode(gradeObject.skin_male)

                end

                if gradeObject.skin_female then

                    userData.job.skin_female = json.decode(gradeObject.skin_female)

                end

            else

               

                local job, grade = 'unemployed', '0'

                local jobObject, gradeObject = ESX.Jobs[job], ESX.Jobs[job].grades[grade]

                userData.job = {}

                userData.job.id    = jobObject.id

                userData.job.name  = jobObject.name

                userData.job.label = jobObject.label

                userData.job.grade        = tonumber(grade)

                userData.job.grade_name   = gradeObject.name

                userData.job.grade_label  = gradeObject.label

                userData.job.grade_salary = gradeObject.salary

                userData.job.skin_male    = {}

                userData.job.skin_female  = {}

            end

            if result[1].loadout then

                userData.loadout = json.decode(result[1].loadout)

                -- Compatibility with old loadouts prior to components update

                for k,v in ipairs(userData.loadout) do

                    if v.components == nil then

                        v.components = {}

                    end

                end

            end

            userData.coords = json.decode(result[1].position)

            cb2()

        end)

    end)

    Async.series(tasks2, cb)

end)

Is this the correct function you’re looking for?

Kind of. What is this wrapped in?
Is this inside another function or something?
Because you need to know your server ID (source, usually) but nowhere in here does it mention source.
Whatever is calling this, needs to pass the player’s server ID.
When triggering a server event on the client, this will pass source automatically, but that’s not happening here. So this seems like it’s running on start up / MySQL.Ready type thing. This won’t work because it’s trying to get player data without having a player to look up.
Unless I am missing something obvious, I can’t help you without knowing more. What script is this from? Your own? Share it maybe?

I’ll send you the full server.lua

AddEventHandler(‘es:playerLoaded’, function(playerId, player)

local tasks = {}

local userData = {

    accounts = {},

    inventory = {},

    job = {},

    loadout = {},

    playerName = GetPlayerName(playerId),

    coords = nil

}

-- Get accounts

table.insert(tasks, function(cb)

    MySQL.Async.fetchAll('SELECT name, money FROM user_accounts WHERE identifier = @identifier', {

        ['@identifier'] = player.getIdentifier()

    }, function(accounts)

        local validAccounts = ESX.Table.Set(Config.Accounts)

        for k,v in ipairs(accounts) do

            if validAccounts[v.name] then

                table.insert(userData.accounts, {

                    name  = v.name,

                    money = v.money,

                    label = Config.AccountLabels[v.name]

                })

            end

        end

        cb()

    end)

end)

-- Get inventory

table.insert(tasks, function(cb)

    MySQL.Async.fetchAll('SELECT item, count FROM user_inventory WHERE identifier = @identifier', {

        ['@identifier'] = player.getIdentifier()

    }, function(inventory)

        local tasks2, foundItems = {}, {}

        for k,v in ipairs(inventory) do

            local item = ESX.Items[v.item]

            if item then

                foundItems[v.item] = true

                table.insert(userData.inventory, {

                    name = v.item,

                    count = v.count,

                    label = item.label,

                    weight = item.weight,

                    usable = ESX.UsableItemsCallbacks[v.item] ~= nil,

                    rare = item.rare,

                    canRemove = item.canRemove

                })

            else

            end

        end

        for name,item in pairs(ESX.Items) do

            if not foundItems[name] then

                table.insert(userData.inventory, {

                    name = name,

                    count = 0,

                    label = item.label,

                    weight = item.weight,

                    usable = ESX.UsableItemsCallbacks[name] ~= nil,

                    rare = item.rare,

                    canRemove = item.canRemove

                })

                local scope = function(item, identifier)

                    table.insert(tasks2, function(cb2)

                        MySQL.Async.execute('INSERT INTO user_inventory (identifier, item, count) VALUES (@identifier, @item, @count)', {

                            ['@identifier'] = identifier,

                            ['@item'] = item,

                            ['@count'] = 0

                        }, function(rowsChanged)

                            cb2()

                        end)

                    end)

                end

                scope(name, player.getIdentifier())

            end

        end

        Async.parallelLimit(tasks2, 5, function(results) end)

        table.sort(userData.inventory, function(a,b)

            return a.label < b.label

        end)

        cb()

    end)

end)

-- Get job and loadout

table.insert(tasks, function(cb)

    local tasks2 = {}

    -- Get job name, grade and coords

    table.insert(tasks2, function(cb2)

        MySQL.Async.fetchAll('SELECT job, job_grade, loadout, position FROM users WHERE identifier = @identifier', {

            ['@identifier'] = GetPlayerIdentifier(source, 1) -- line that i changed.

        }, function(result)

            local job, grade = result[1].job, tostring(result[1].job_grade) -- line 110

            if ESX.DoesJobExist(job, grade) then

                local jobObject, gradeObject = ESX.Jobs[job], ESX.Jobs[job].grades[grade]

                userData.job = {}

                userData.job.id    = jobObject.id

                userData.job.name  = jobObject.name

                userData.job.label = jobObject.label

                userData.job.grade        = tonumber(grade)

                userData.job.grade_name   = gradeObject.name

                userData.job.grade_label  = gradeObject.label

                userData.job.grade_salary = gradeObject.salary

                userData.job.skin_male    = {}

                userData.job.skin_female  = {}

                if gradeObject.skin_male then

                    userData.job.skin_male = json.decode(gradeObject.skin_male)

                end

                if gradeObject.skin_female then

                    userData.job.skin_female = json.decode(gradeObject.skin_female)

                end

            else

               

                local job, grade = 'unemployed', '0'

                local jobObject, gradeObject = ESX.Jobs[job], ESX.Jobs[job].grades[grade]

                userData.job = {}

                userData.job.id    = jobObject.id

                userData.job.name  = jobObject.name

                userData.job.label = jobObject.label

                userData.job.grade        = tonumber(grade)

                userData.job.grade_name   = gradeObject.name

                userData.job.grade_label  = gradeObject.label

                userData.job.grade_salary = gradeObject.salary

                userData.job.skin_male    = {}

                userData.job.skin_female  = {}

            end

            if result[1].loadout then

                userData.loadout = json.decode(result[1].loadout)

                -- Compatibility with old loadouts prior to components update

                for k,v in ipairs(userData.loadout) do

                    if v.components == nil then

                        v.components = {}

                    end

                end

            end

            userData.coords = json.decode(result[1].position)

            cb2()

        end)

    end)

    Async.series(tasks2, cb)

end)

-- Run Tasks

Async.parallel(tasks, function(results)

    local xPlayer = CreateExtendedPlayer(player, userData.accounts, userData.inventory, userData.job, userData.loadout, userData.playerName, userData.coords)

    xPlayer.getMissingAccounts(function(missingAccounts)

        if #missingAccounts > 0 then

            for i=1, #missingAccounts, 1 do

                table.insert(xPlayer.accounts, {

                    name = missingAccounts[i],

                    money = 0,

                    label = Config.AccountLabels[missingAccounts[i]]

                })

            end

            xPlayer.createAccounts(missingAccounts)

        end

        ESX.Players[playerId] = xPlayer

        TriggerEvent('esx:playerLoaded', playerId, xPlayer)

        xPlayer.triggerEvent('esx:playerLoaded', {

            identifier = xPlayer.identifier,

            accounts = xPlayer.getAccounts(),

            coords = xPlayer.getCoords(),

            inventory = xPlayer.getInventory(),

            job = xPlayer.getJob(),

            loadout = xPlayer.getLoadout(),

            money = xPlayer.getMoney(),

            maxWeight = xPlayer.maxWeight

        })

        xPlayer.displayMoney(xPlayer.getMoney())

        xPlayer.triggerEvent('esx:createMissingPickups', ESX.Pickups)

    end)

end)

end)

AddEventHandler(‘playerDropped’, function(reason)

local playerId = source

local xPlayer = ESX.GetPlayerFromId(playerId)

if xPlayer then

    TriggerEvent('esx:playerDropped', playerId, reason)

    ESX.SavePlayer(xPlayer, function()

        ESX.Players[playerId] = nil

        ESX.LastPlayerData[playerId] = nil

    end)

end

end)

RegisterNetEvent(‘esx:updateCoords’)

AddEventHandler(‘esx:updateCoords’, function(coords)

local xPlayer = ESX.GetPlayerFromId(source)

if xPlayer then

    xPlayer.updateCoords(coords)

end

end)

RegisterNetEvent(‘esx:giveInventoryItem’)

AddEventHandler(‘esx:giveInventoryItem’, function(target, type, itemName, itemCount)

local playerId = source

local sourceXPlayer = ESX.GetPlayerFromId(playerId)

local targetXPlayer = ESX.GetPlayerFromId(target)

if type == 'item_standard' then

    local sourceItem = sourceXPlayer.getInventoryItem(itemName)

    local targetItem = targetXPlayer.getInventoryItem(itemName)

    if itemCount > 0 and sourceItem.count >= itemCount then

        if targetXPlayer.canCarryItem(itemName, itemCount) then

            sourceXPlayer.removeInventoryItem(itemName, itemCount)

            targetXPlayer.addInventoryItem   (itemName, itemCount)

            sourceXPlayer.showNotification(_U('gave_item', itemCount, sourceItem.label, targetXPlayer.name))

            targetXPlayer.showNotification(_U('received_item', itemCount, sourceItem.label, sourceXPlayer.name))

        else

            sourceXPlayer.showNotification(_U('ex_inv_lim', targetXPlayer.name))

        end

    else

        sourceXPlayer.showNotification(_U('imp_invalid_quantity'))

    end

elseif type == 'item_money' then

    if itemCount > 0 and sourceXPlayer.getMoney() >= itemCount then

        sourceXPlayer.removeMoney(itemCount)

        targetXPlayer.addMoney   (itemCount)

        sourceXPlayer.showNotification(_U('gave_money', ESX.Math.GroupDigits(itemCount), targetXPlayer.name))

        targetXPlayer.showNotification(_U('received_money', ESX.Math.GroupDigits(itemCount), sourceXPlayer.name))

    else

        sourceXPlayer.showNotification(_U('imp_invalid_amount'))

    end

elseif type == 'item_account' then

    if itemCount > 0 and sourceXPlayer.getAccount(itemName).money >= itemCount then

        sourceXPlayer.removeAccountMoney(itemName, itemCount)

        targetXPlayer.addAccountMoney   (itemName, itemCount)

        sourceXPlayer.showNotification(_U('gave_account_money', ESX.Math.GroupDigits(itemCount), Config.AccountLabels[itemName], targetXPlayer.name))

        targetXPlayer.showNotification(_U('received_account_money', ESX.Math.GroupDigits(itemCount), Config.AccountLabels[itemName], sourceXPlayer.name))

    else

        sourceXPlayer.showNotification(_U('imp_invalid_amount'))

    end

elseif type == 'item_weapon' then

    if sourceXPlayer.hasWeapon(itemName) then

        local weaponLabel = ESX.GetWeaponLabel(itemName)

        if not targetXPlayer.hasWeapon(itemName) then

            local weaponNum, weapon = sourceXPlayer.getWeapon(itemName)

            itemCount = weapon.ammo

            sourceXPlayer.removeWeapon(itemName)

            targetXPlayer.addWeapon(itemName, itemCount)

            if itemCount > 0 then

                sourceXPlayer.showNotification(_U('gave_weapon_withammo', weaponLabel, itemCount, targetXPlayer.name))

                targetXPlayer.showNotification(_U('received_weapon_withammo', weaponLabel, itemCount, sourceXPlayer.name))

            else

                sourceXPlayer.showNotification(_U('gave_weapon', weaponLabel, targetXPlayer.name))

                targetXPlayer.showNotification(_U('received_weapon', weaponLabel, sourceXPlayer.name))

            end

        else

            sourceXPlayer.showNotification(_U('gave_weapon_hasalready', targetXPlayer.name, weaponLabel))

            targetXPlayer.showNotification(_U('received_weapon_hasalready', sourceXPlayer.name, weaponLabel))

        end

    end

elseif type == 'item_ammo' then

    if sourceXPlayer.hasWeapon(itemName) then

        if targetXPlayer.hasWeapon(itemName) then

            local weaponNum, weapon = sourceXPlayer.getWeapon(itemName)

            if weapon.ammo >= itemCount then

                sourceXPlayer.removeWeaponAmmo(itemName, itemCount)

                targetXPlayer.addWeaponAmmo(itemName, itemCount)

                sourceXPlayer.showNotification(_U('gave_weapon_ammo', itemCount, weapon.label, targetXPlayer.name))

                targetXPlayer.showNotification(_U('received_weapon_ammo', itemCount, weapon.label, sourceXPlayer.name))

            end

        else

            sourceXPlayer.showNotification(_U('gave_weapon_noweapon', targetXPlayer.name))

            targetXPlayer.showNotification(_U('received_weapon_noweapon', sourceXPlayer.name, weapon.label))

        end

    end

end

end)

RegisterNetEvent(‘esx:removeInventoryItem’)

AddEventHandler(‘esx:removeInventoryItem’, function(type, itemName, itemCount)

local playerId = source

local xPlayer = ESX.GetPlayerFromId(source)

if type == 'item_standard' then

    if itemCount == nil or itemCount < 1 then

        xPlayer.showNotification(_U('imp_invalid_quantity'))

    else

        local xItem = xPlayer.getInventoryItem(itemName)

        if (itemCount > xItem.count or xItem.count < 1) then

            xPlayer.showNotification(_U('imp_invalid_quantity'))

        else

            xPlayer.removeInventoryItem(itemName, itemCount)

            local pickupLabel = ('~y~%s~s~ [~b~%s~s~]'):format(xItem.label, itemCount)

            ESX.CreatePickup('item_standard', itemName, itemCount, pickupLabel, playerId)

            xPlayer.showNotification(_U('threw_standard', itemCount, xItem.label))

        end

    end

elseif type == 'item_money' then

    if itemCount == nil or itemCount < 1 then

        xPlayer.showNotification(_U('imp_invalid_amount'))

    else

        local playerCash = xPlayer.getMoney()

        if (itemCount > playerCash or playerCash < 1) then

            xPlayer.showNotification(_U('imp_invalid_amount'))

        else

            xPlayer.removeMoney(itemCount)

            local pickupLabel = ('~y~%s~s~ [~g~%s~s~]'):format(_U('cash'), _U('locale_currency', ESX.Math.GroupDigits(itemCount)))

            ESX.CreatePickup('item_money', 'money', itemCount, pickupLabel, playerId)

            xPlayer.showNotification(_U('threw_money', ESX.Math.GroupDigits(itemCount)))

        end

    end

elseif type == 'item_account' then

    if itemCount == nil or itemCount < 1 then

        xPlayer.showNotification(_U('imp_invalid_amount'))

    else

        local account = xPlayer.getAccount(itemName)

        if (itemCount > account.money or account.money < 1) then

            xPlayer.showNotification(_U('imp_invalid_amount'))

        else

            xPlayer.removeAccountMoney(itemName, itemCount)

            local pickupLabel = ('~y~%s~s~ [~g~%s~s~]'):format(account.label, _U('locale_currency', ESX.Math.GroupDigits(itemCount)))

            ESX.CreatePickup('item_account', itemName, itemCount, pickupLabel, playerId)

            xPlayer.showNotification(_U('threw_account', ESX.Math.GroupDigits(itemCount), string.lower(account.label)))

        end

    end

elseif type == 'item_weapon' then

    itemName = string.upper(itemName)

    if xPlayer.hasWeapon(itemName) then

        local weaponNum, weapon = xPlayer.getWeapon(itemName)

        xPlayer.removeWeapon(itemName)

        local pickupLabel = ('~y~%s~s~ [~g~%s~s~ ammo]'):format(weapon.label, weapon.ammo)

        ESX.CreatePickup('item_weapon', itemName, weapon.ammo, pickupLabel, playerId, weapon.components)

        if weapon.ammo > 0 then

            xPlayer.showNotification(_U('threw_weapon_ammo', weapon.label, weapon.ammo))

        else

            xPlayer.showNotification(_U('threw_weapon', weapon.label))

        end

    end

end

end)

RegisterNetEvent(‘esx:useItem’)

AddEventHandler(‘esx:useItem’, function(itemName)

local xPlayer = ESX.GetPlayerFromId(source)

local count = xPlayer.getInventoryItem(itemName).count

if count > 0 then

    ESX.UseItem(source, itemName)

else

    xPlayer.showNotification(_U('act_imp'))

end

end)

RegisterNetEvent(‘esx:onPickup’)

AddEventHandler(‘esx:onPickup’, function(id)

local pickup, xPlayer, success = ESX.Pickups[id], ESX.GetPlayerFromId(source)

if pickup then

    if pickup.type == 'item_standard' then

        if xPlayer.canCarryItem(pickup.name, pickup.count) then

            xPlayer.addInventoryItem(pickup.name, pickup.count)

            success = true

        else

            xPlayer.showNotification(_U('threw_cannot_pickup'))

        end

    elseif pickup.type == 'item_money' then

        success = true

        xPlayer.addMoney(pickup.count)

    elseif pickup.type == 'item_account' then

        success = true

        xPlayer.addAccountMoney(pickup.name, pickup.count)

    elseif pickup.type == 'item_weapon' then

        if xPlayer.hasWeapon(pickup.name) then

            xPlayer.showNotification(_U('threw_weapon_already'))

        else

            success = true

            xPlayer.addWeapon(pickup.name, pickup.count)

            for k,v in ipairs(pickup.components) do

                xPlayer.addWeaponComponent(pickup.name, v)

            end

        end

    end

    if success then

        ESX.Pickups[id] = nil

        TriggerClientEvent('esx:removePickup', -1, id)

    end

end

end)

ESX.RegisterServerCallback(‘esx:getPlayerData’, function(source, cb)

local xPlayer = ESX.GetPlayerFromId(source)

cb({

    identifier   = xPlayer.identifier,

    accounts     = xPlayer.getAccounts(),

    inventory    = xPlayer.getInventory(),

    job          = xPlayer.getJob(),

    loadout      = xPlayer.getLoadout(),

    money        = xPlayer.getMoney()

})

end)

ESX.RegisterServerCallback(‘esx:getOtherPlayerData’, function(source, cb, target)

local xPlayer = ESX.GetPlayerFromId(target)

cb({

    identifier   = xPlayer.identifier,

    accounts     = xPlayer.getAccounts(),

    inventory    = xPlayer.getInventory(),

    job          = xPlayer.getJob(),

    loadout      = xPlayer.getLoadout(),

    money        = xPlayer.getMoney()

})

end)

ESX.RegisterServerCallback(‘esx:getPlayerNames’, function(source, cb, players)

players[source] = nil

for playerId,v in pairs(players) do

    local xPlayer = ESX.GetPlayerFromId(playerId)

    if xPlayer then

        players[playerId] = xPlayer.getName()

    else

        players[playerId] = nil

    end

end

cb(players)

end)

ESX.StartDBSync()

ESX.StartPayCheck()

Oh gosh…
In future, please just share the file using this button, at the top of the reply text box;

image

Or put all your code inside a single code block, like this;

```lua
Code here
```

The way you shared it makes it so hard to read, as you can see.

Anyway, this fix is easy…
Where we put source, replace with playerId.
Like this;

['@identifier'] = GetPlayerIdentifier(playerId, 1)

JUST LIKE I HAD SAID TO IN MY PREVIOUS RESPONSE!!!

Let me teach you something. Because without being able to understand this DAY ONE concept, you might as well give up. The fact that this was so easy to solve and took so long because you didn’t understand what a player’s server ID is, has now pissed me off. Look below;

AddEventHandler('es:playerLoaded', function(playerId, player)
    -- Code
end)

It literally says playerId as the first parameter. It’s usually called source and that is a player’s server ID. So when I said to replace source with whatever they are calling it in that script, that is what I meant. Now please go and read the FiveM Documentation and the ESX Documentation before you do ANYTHING else. Because you are far from being ready to be a server dev… Sorry to be blunt, but if you couldn’t fix this yourself OR with my clear instructions, then you’re never going to get anywhere.

I never said I was a developer?? I needed assistance and I have been struggling to get service so I cannot see half your messages. Please don’t accuse me of being something I’m not.

This didn’t fix the issue.

['@identifier'] = GetPlayerIdentifier(playerId, 1) didn't change a thing


ng.

Just to let you know, the 109 is the 110 line, I removed an unnecessary space.

Could you possibly assist me further, this didn’t fix my issue.

This is the last message I will send you.
['@identifier'] = ESX.GetPlayerFromId(playerId).identifier
If that doesn’t work, you have broken something by changing stuff without knowing what you are doing and you should reinstall es_extended. Good luck and good bye. :spades: