wbthomason / packer.nvim

A use-package inspired plugin manager for Neovim. Uses native packages, supports Luarocks dependencies, written in Lua, allows for expressive config
MIT License
7.82k stars 266 forks source link

Error running config for X: attempt to call upvalue '' (a nil value) #996

Closed Dich0tomy closed 2 years ago

Dich0tomy commented 2 years ago

Steps to reproduce

I don't know if this is directly related to packer, probably more my lua scripting skills, but it seems like it's packer's issue. I have a few helpers than help me define my plugins, the most basic example looks like this:

-- config.utils.plugin
local notify_error = function(error)
    vim.notify_once('[ERROR] While loading plugin\n' .. error, vim.log.levels.ERROR)
end

local extract_requires_name = function(name)
    return name:gsub('.nvim$', ''):gsub('.*/', '')
end

return {

use_plugins = function(plugins)
    local status, packer_mod = xpcall(require, notify_error, 'packer')

    if status then
        packer_mod.startup(function(use)
            for _, plugin in ipairs(plugins) do
                use(plugin)
            end
        end)
    end
end,

with_setup = function(name, config)
    return {
        name,
        config = function() 
            local plain_name = name:gsub('.nvim$', ''):gsub('.*/', '')

            local status, mod = xpcall(require, notify_error, plain_name)
            if status then
                mod.setup(config) 
            end
        end
    }
end

}
-- config.plugins
local pu = require 'config.utils.plugin'

pu.use_plugins {
    'wbthomason/packer.nvim',
    pu.with_setup('ggandor/lightspeed.nvim', {
        jump_to_unique_chars = { safety_timeout = 200 },
    }),
}

Now after I PackerSync or restart I get

packer.nvim: Error running config for lightspeed.nvim: [strnig "..."]:0: attempt to call upvalue '' (a nil value)

I think it's packer related, because if I pretty print the output from with_setup I get proper results.

Actual behaviour

Error.

Expected behaviour

Not error.

packer files

Plugin specification file(s) Post or link your plugin specification files here, if you aren't able to provide a minimal reproducer
packer log file Post the contents of ~/.cache/nvim/packer.nvim.log here Only cleaning cancelled.
packer compiled file Post the contents of `packer_compiled.vim` here ```lua -- Automatically generated packer.nvim plugin loader code if vim.api.nvim_call_function('has', {'nvim-0.5'}) ~= 1 then vim.api.nvim_command('echohl WarningMsg | echom "Invalid Neovim version for packer.nvim! | echohl None"') return end vim.api.nvim_command('packadd packer.nvim') local no_errors, error_msg = pcall(function() local time local profile_info local should_profile = false if should_profile then local hrtime = vim.loop.hrtime profile_info = {} time = function(chunk, start) if start then profile_info[chunk] = hrtime() else profile_info[chunk] = (hrtime() - profile_info[chunk]) / 1e6 end end else time = function(chunk, start) end end local function save_profiles(threshold) local sorted_times = {} for chunk_name, time_taken in pairs(profile_info) do sorted_times[#sorted_times + 1] = {chunk_name, time_taken} end table.sort(sorted_times, function(a, b) return a[2] > b[2] end) local results = {} for i, elem in ipairs(sorted_times) do if not threshold or threshold and elem[2] > threshold then results[i] = elem[1] .. ' took ' .. elem[2] .. 'ms' end end _G._packer = _G._packer or {} _G._packer.profile_output = results end time([[Luarocks path setup]], true) local package_path_str = "C:\\Users\\B4mbus\\AppData\\Local\\Temp\\nvim\\packer_hererocks\\2.1.0-beta3\\share\\lua\\5.1\\?.lua;C:\\Users\\B4mbus\\AppData\\Local\\Temp\\nvim\\packer_hererocks\\2.1.0-beta3\\share\\lua\\5.1\\?\\init.lua;C:\\Users\\B4mbus\\AppData\\Local\\Temp\\nvim\\packer_hererocks\\2.1.0-beta3\\lib\\luarocks\\rocks-5.1\\?.lua;C:\\Users\\B4mbus\\AppData\\Local\\Temp\\nvim\\packer_hererocks\\2.1.0-beta3\\lib\\luarocks\\rocks-5.1\\?\\init.lua" local install_cpath_pattern = "C:\\Users\\B4mbus\\AppData\\Local\\Temp\\nvim\\packer_hererocks\\2.1.0-beta3\\lib\\lua\\5.1\\?.so" if not string.find(package.path, package_path_str, 1, true) then package.path = package.path .. ';' .. package_path_str end if not string.find(package.cpath, install_cpath_pattern, 1, true) then package.cpath = package.cpath .. ';' .. install_cpath_pattern end time([[Luarocks path setup]], false) time([[try_loadstring definition]], true) local function try_loadstring(s, component, name) local success, result = pcall(loadstring(s), name, _G.packer_plugins[name]) if not success then vim.schedule(function() vim.api.nvim_notify('packer.nvim: Error running ' .. component .. ' for ' .. name .. ': ' .. result, vim.log.levels.ERROR, {}) end) end return result end time([[try_loadstring definition]], false) time([[Defining packer_plugins]], true) _G.packer_plugins = { ["lightspeed.nvim"] = { config = { "\27LJ\2\nž\1\0\0\6\4\6\0\23-\0\0\0-\2\1\0B\0\2\0026\1\0\0009\1\1\1'\3\2\0\18\4\0\0B\1\3\0016\1\0\0009\1\1\1-\3\2\0B\1\2\0016\1\3\0006\3\4\0-\4\3\0\18\5\0\0B\1\4\3\15\0\1\0X\3\3€9\3\5\2-\5\2\0B\3\2\1K\0\1\0\0\0\0À\1À\1\0\nsetup\frequire\vxpcall\17Plain name: \17pretty_print\bvim\0" }, loaded = true, path = "C:\\Users\\B4mbus\\AppData\\Local\\nvim-data\\site\\pack\\packer\\start\\lightspeed.nvim", url = "https://github.com/ggandor/lightspeed.nvim" }, ["packer.nvim"] = { loaded = true, path = "C:\\Users\\B4mbus\\AppData\\Local\\nvim-data\\site\\pack\\packer\\start\\packer.nvim", url = "https://github.com/wbthomason/packer.nvim" } } time([[Defining packer_plugins]], false) -- Config for: lightspeed.nvim time([[Config for lightspeed.nvim]], true) try_loadstring("\27LJ\2\nž\1\0\0\6\4\6\0\23-\0\0\0-\2\1\0B\0\2\0026\1\0\0009\1\1\1'\3\2\0\18\4\0\0B\1\3\0016\1\0\0009\1\1\1-\3\2\0B\1\2\0016\1\3\0006\3\4\0-\4\3\0\18\5\0\0B\1\4\3\15\0\1\0X\3\3€9\3\5\2-\5\2\0B\3\2\1K\0\1\0\0\0\0À\1À\1\0\nsetup\frequire\vxpcall\17Plain name: \17pretty_print\bvim\0", "config", "lightspeed.nvim") time([[Config for lightspeed.nvim]], false) if should_profile then save_profiles() end end) if not no_errors then error_msg = error_msg:gsub('"', '\\"') vim.api.nvim_command('echohl ErrorMsg | echom "Error in packer_compiled: '..error_msg..'" | echom "Please check your config for correctness" | echohl None') end ```
djdv commented 2 years ago

I've gotten this error as well for a different plugin (trying to migrate to the mason.nvim plugin), however I can't seem to reproduce it consistently.

~~I have to imagine it's related to this https://github.com/wbthomason/packer.nvim/issues/958 Whether config bodies are executed or not seems somewhat arbitrary at the moment. When I start nvim, they typically are not run, if I call :PackerCompile after starting nvim, sometimes some of the body seems to get executed, but I get lots of nil related errors from within plugin code itself. I'm assuming this has to do with setup not being called from within config. Not really sure.~~

Edit: Ended up being unrelated. (;´∀`)

akinsho commented 2 years ago

The upvalue error is probably one of the most common issues people encounter, and a sad but easy hole to fall into. To explain it a bit, the upvalue error occurs when inside the config field a user references any variable not created inside the config, unless it is a global.

e.g.

local variable = 'thing'
use {'plugin/thing', config = function()
   require('plugin-name').setup(variable) -- <-- This will be an error because variable is an upvalue
end}

I'm not going to read through your config to identify the upvalue, but that error means there definitely is one.

This happens because your config is essentially stringified so it won't be able to hold references to values defined outside the scope of a function unless that value is global so always available

Dich0tomy commented 2 years ago

@akinsho This helped me solve the issue! Thank you very much.

Dich0tomy commented 2 years ago

@akinsho Sorry for the confusion. It actually didn't, the config doesn't seem to run (e.g. for nvim-tree it doesn't run require 'nvim-tree'.setup() and I don't get NvimTreeToggle and other commands.

Is there anything I can do to make the upvalues available? Anything, cloning, metatables, function enviroments? I don't know lua well enough to think of something specific.

akinsho commented 2 years ago

You can make them globals I haven't read through your configuration files so I don't know what these values are, but I have helpers I use all throughout my config. I put them inside a lua table and then attach them to the global object. You are allowed to access global checks inside of a config function

Dich0tomy commented 2 years ago

@akinsho Thanks.