This is really annoying, I just discovered a very funny bug.
The first log part is from the function called in the thread.
The 2nd log part came from the log of the command below (“load_crosshair_values”).

The code part it underneath

MainThrd/ Access denied for command cl_customcrosshair.
MainThrd/ Access denied for command cl_crosshairdot.
MainThrd/ Access denied for command cl_crosshairsize.
MainThrd/ Access denied for command cl_crosshairstyle.
MainThrd/ Access denied for command cl_crosshairthickness.
MainThrd/ Access denied for command cl_crosshairgap.
MainThrd/ Access denied for command cl_crosshair_drawoutline.
MainThrd/ Access denied for command cl_crosshair_outlinethickness.
MainThrd/ Access denied for command cl_crosshaircolor_r.
MainThrd/ Access denied for command cl_crosshaircolor_g.
MainThrd/ Access denied for command cl_crosshaircolor_b.
MainThrd/ Access denied for command cl_crosshair_dynamic_splitdist.
MainThrd/ Access denied for command cl_crosshair_dynamic_splitalpha_innermod.
MainThrd/ Access denied for command cl_crosshair_dynamic_maxdist_splitratio.
MainThrd/ 
MainThrd/ 
MainThrd/ cl_customcrosshair true
MainThrd/ cl_crosshairdot false
MainThrd/ cl_crosshairsize 0.0
MainThrd/ cl_crosshairstyle 0
MainThrd/ cl_crosshairthickness 0.0
MainThrd/ cl_crosshairgap 0.0
MainThrd/ cl_crosshair_drawoutline false
MainThrd/ cl_crosshair_outlinethickness 0.0
MainThrd/ cl_crosshaircolor_r 0
MainThrd/ cl_crosshaircolor_g 0
MainThrd/ cl_crosshaircolor_b 0
MainThrd/ cl_crosshaircolor_a 0
MainThrd/ cl_crosshair_dynamic_splitdist 0.0
MainThrd/ cl_crosshair_dynamic_splitalpha_innermod 0.0
MainThrd/ cl_crosshair_dynamic_maxdist_splitratio 0.0

CODE

function sheesh()
    for k, v in ipairs(CacheRegistries) do
        local cacheVal = Utils.GetValue(v.name)
        if cacheVal ~= nil then
            -- print(v.commandName .. " " .. tostring(cacheVal))
            ExecuteCommand(v.commandName .. " " .. tostring(cacheVal))
        end
    end
end

Citizen.CreateThread(function()
    -- Execute Commands --
    sheesh()
end)

RegisterCommand('load_crosshair_values', function()
    for k, v in ipairs(CacheRegistries) do
        local cacheVal = Utils.GetValue(v.name)
        if cacheVal ~= nil then
            print(v.commandName .. " " .. tostring(cacheVal))
            ExecuteCommand(v.commandName .. " " .. tostring(cacheVal))
        end
    end
end, false)

UPDATE

I also tried calling the “load_crosshair_values” command in the thread, but that didn’t work either.

@nta, why does the rights system deny the command by code but not when a player calls the command?