6

TL;DR

How to find where exactly vim or nvim error started (which file?) when I'm interested in fixing the actual issue and not just removing the bad plugin? Anything better than strace and guesswork to find the error origin?

Issue

I often add a plugin to my vim or nvim config and end up getting errors on hooks (buffer open, close, write):

"test.py" [New] 0L, 0C written
Error detected while processing function 343[12]..272:
line    8:
E716: Key not present in Dictionary: _exec
E116: Invalid arguments for function get(a:args, 'exec', a:1['_exec'])
E15: Invalid expression: get(a:args, 'exec', a:1['_exec'])

The problem is, I have no idea where those come from, only get some line number of unknown file and I know it's not my vim/nvim config file.

cprn
  • 1,561
  • 1
  • 19
  • 25
  • Is that the whole stack trace. Do you 343 files loaded by `:scriptnames`? – FDinoff Oct 04 '16 at 23:04
  • This isn't `stacktrace` output, it's all that `vim` prints when I try to open an empty `test.py` file. Will check `:scriptnames` asap but yeah, I load plugins via manager so it's possible it's that many files. Is that what it is - the number of opened files? – cprn Oct 05 '16 at 06:13
  • This is obfuscated to me. function 343[12]..272: I don't know what it means normally its the name of the function which is easily found. But it seems like a number. I know that sometimes vim uses the order the file was loaded as a unique identifier for script local functions but I still though the name came with it. – FDinoff Oct 05 '16 at 14:48
  • Just to satisfy mine and yours curiosity: I have total of 114 vim-scripts loaded (27 plugins). So it seems irrelevant. – cprn Oct 05 '16 at 22:16

1 Answers1

7

Somewhere, you have a plugin that has defined a dictionary with anonymous-functions (check the help related to this tag).

For the curious ones, it's done this way:

let d = {}
function! d.whatever() abort
   throw "blah"
endfunction

When you execute this function, you'll get the kind of error you're currently observing. That's why I stopped working this way to prefer:

let d = {}
function s:whatever() abort
   throw "blah"
endfunction
let d.whatever = function('s:whatever') " a workaround is required for older versions of vim
" At least this way I'll get a `<SNR>42_whatever` in the exception throwpoint, and thus a scriptname.

That's the why. Now, back to your problem, AFAIK, the only things you'll be able to know are the two functions that have been called:

  • in line 12 of :function {343}, you've called
  • :function {272} which contains an error at line 8.

Thanks to these two commands (may be prefixed with :verbose, I don't remember exactly), you'll get the source code of the two functions, which you should be able to use in order to grep your plugins to know where it appears.

Luc Hermitte
  • 31,979
  • 7
  • 69
  • 83
  • Hahahahhahahaha I knew about `:function` but I would _never_ guess `{343}` is a function name :D Thanks a bunch! – cprn Oct 05 '16 at 22:10