From d9d8c660fd5559d928c8870a21970a375674e310 Mon Sep 17 00:00:00 2001 From: Oleksandr Chekhovskyi Date: Tue, 24 Feb 2026 00:33:13 +0200 Subject: [PATCH] fix(watch): invalid joined path #37973 Problem: When vim._watch.watch() is used to watch a single file, libuv returns the basename as the filename argument in the callback. The code joins this with the watched path, producing a nonsensical path like "/path/to/file.lua/file.lua", which causes ENOTDIR errors on subsequent fs_stat calls. Solution: Check whether the watched path is a directory before joining the filename. When watching a file, ignore the filename from libuv and use the watched path directly. --- runtime/lua/vim/_watch.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/runtime/lua/vim/_watch.lua b/runtime/lua/vim/_watch.lua index 8bfa61cf1e..3f7438dcac 100644 --- a/runtime/lua/vim/_watch.lua +++ b/runtime/lua/vim/_watch.lua @@ -69,10 +69,12 @@ function M.watch(path, opts, callback) local uvflags = opts and opts.uvflags or {} local handle = assert(uv.new_fs_event()) + local watching_dir = (uv.fs_stat(path) or {}).type == 'directory' + local _, start_err, start_errname = handle:start(path, uvflags, function(err, filename, events) assert(not err, err) local fullpath = path - if filename then + if filename and watching_dir then fullpath = vim.fs.normalize(vim.fs.joinpath(fullpath, filename)) end