Does it? I'm not sure. I'm getting this error, and it seems to be looking for a nonexistent cache folder:

E282: Cannot read from "/var/folders/yh/z3ydby_56qz7mltrddsv3lqw0000gn/T/vi3voZp/0"

It only happens when the line that uses system() is uncommented out. I've already tried histdel(':'). I'm not sure if that also includes the system() function. Nothing seems to work. Is there a histdel('*') to delete the whole cache? I've also tried deleting lines from .viminfo but I'm still getting the same error. I'm using macOS Ventura. Not sure if that helps. I also tried reading the documentation but it's not mentioned there if the result of system() is cached or not.

" Read the contents of the file separated into lines
let lines = join(getline(1, '$'), '\n')

" Assign an empty string for annotations
let annotations = ''

" Separate markup from content into a list
let contents = split(lines, '\v(\<[^<]*\>|[^<]+)\zs')

" Add contents into annotations in JSON format
for i in range(len(contents))
  " Check if it's a markup or content and label it with the right key
  if match(contents[i], '<[^>]*>') > -1
    let annotations .= '{"markup":'
    let annotations .= '{"text":'

 " Check if it's the last entry and put a comma after the entry if it is not
 if i < len(contents) - 1
   let annotations .= ' "' . contents[i] . '"},'
   let annotations .= ' "' . contents[i] . '"}'

" Generate the JSON output
let json = '{"annotation":' . annotations . '}'

" Pass the JSON data to the LanguageTool API
let url = g:languagetool_server_root . '/v2/check'
let response = system('curl -X POST --header "Content-Type: application/x-www-form-urlencoded" --header "Accept: application/json" -d "language=' . shellescape(g:languagetool_default) . '&enabledOnly=false&data=' . shellescape(URLEncode(json)) . '"' . shellescape(url) . '"')

I'm not sure if it's curl, but from what I read, it doesn't cache on the client-side.

I tried :set verbose=5 like @ChristianBrabandt suggested and this was the output:

Calling shell to execute: "(curl -X POST --header "Content-Type: application/x-www-form-urlencoded" --header "Accept: application/json" -d "language='en-US'&enabledOnly=false&data='%7b%22annotation%22%3a%
gn/T/vQGIEUY/2 2>&1"
Error detected while processing function languagetool#CheckGrammar:
line   32:
E282: Cannot read from "/var/folders/yh/z3ydby_56qz7mltrddsv3lqw0000gn/T/vQGIEUY/2"
  • no, it doesn't cache system() (and that wouln't make sense). However it uses tempfiles for retrieving the command output for system(). In your case, it looks like something on your system possibly deleted the folder where vim creates those temp files. Or the system may file for other reasons, e.g. wrong shell settings Jul 24, 2023 at 6:07
  • Sorry. I meant if the output is cached. Is there anything I can do to move forward in debugging this? Like clear the list of temporary files? It's weird. It doesn't make sense to me why it stores the output. The only thing I can think of why it stores it in a temporary file is for when the output is from a remote origin. If it is, isn't it better to just say that the internet connection is required to perform the task? If it's performance reasons, it goes over my head. Jul 24, 2023 at 6:17
  • The only caching that exists within Vim between system() calls is when the user assigns their output to a variable. histdel() and .viminfo have nothing to do with this. Give us a minimal reproducable example that we can play with in $ vim --clean.
    – romainl
    Jul 24, 2023 at 6:25
  • Thanks! I added the related codes that are causing the error. Jul 24, 2023 at 6:28
  • 1
    @D.BenKnoble IIRC the v* is created uniquely after re-starting Vim. You can check: vim --clean -c ':echo tempname()'. The folder should be there, just the temp files will only be created on demand. Jul 24, 2023 at 13:50

1 Answer 1


It worked! I reconstructed the curl command and separated the header and body (including the data to be passed) into variables. It was an issue with quotation marks. shellescape() encloses the variable in single quotation marks.

This is the code that worked:

let content_type = 'Content-Type: application/x-www-form-urlencoded'
let accept = 'Accept: application/json'
let data = 'language=' . g:languagetool_default . '&enabledOnly=false&data=' . json
let url = g:languagetool_server_root . '/v2/check'
let response = system('curl -s -X POST --header ' . shellescape(content_type) . ' --header ' . shellescape(accept) . ' -d ' . shellescape(data) . ' ' . shellescape(url))

I still don't understand why there was a temporary file being loaded by system() that doesn't exist, though.

I spoke too soon. It's doing it again in the reconstructed curl command. I guess it wasn't the issue with the quotation mark that was causing the issue with the temporary files.

My bad. It's not related to this question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.