Subject: bug#78712: 31.0.50; definition is void in file-notify

From: Michael Albinus <[email-masked]>
Date: Fri, 06 Jun 2025 14:49:49 +0200

Al Haji-Ali <[email-masked]> writes:

Hi,

> I am running into an issue (on MacOS) where a file-watcher gets called with a specific set of actions, which lead to the error
>
> ,----
> | file-notify--call-handler: Symbol's function definition is void: nil
> `----
>
> Here's the full stack trace:
>
> ,----
> | Debugger entered--Lisp error: (void-function nil)
> |   nil((63 attribute-changed "[redacted]"))
> |   file-notify--call-handler(#s(file-notify--watch :directory "[redacted]" :filename "[redacted]" :callback nil) 63 attribute-changed "[redacted]" nil)
> |   file-notify--handle-event(63 (renamed attribute-changed deleted) "[redacted]" nil)
> |   file-notify--callback-kqueue((63 (rename attrib delete) "[redacted]"))
> |   file-notify-handle-event((file-notify (63 (rename attrib delete) "[redacted]") file-notify--callback-kqueue))
> |   funcall-interactively(file-notify-handle-event (file-notify (63 (rename attrib delete) "[redacted]") file-notify--callback-kqueue))
> |   command-execute(file-notify-handle-event nil [(file-notify (63 (rename attrib delete) "[redacted]") file-notify--callback-kqueue)] t)
> `----

--8<---------------cut here---------------start------------->8---
> |   file-notify-handle-event((file-notify (63 (rename attrib delete) "[redacted]") file-notify--callback-kqueue))
--8<---------------cut here---------------end--------------->8---

This looks wrong. The event in the object, file-notify-handle-event is
called with, has only three slots: (63 (rename attrib delete) "[redacted]").

There must be 4 slots, like in (tested on my FreeBDS14 VM):

--8<---------------cut here---------------start------------->8---
file-notify-handle-event((file-notify (6 (rename) "xxx" "yyy") file-notify--callback-kqueue))
--8<---------------cut here---------------end--------------->8---

> and here's some code that replicates the error (I can't figure out now to replicate the event itself)
>
> (let* ((desc (car (hash-table-keys file-notify-descriptors)))
>        (watch (gethash desc file-notify-descriptors))
>        (action '(rename atttrib delete)))
>   (when desc
>     (file-notify-handle-event
>      (make-file-notify
>       :-event (list desc action (file-notify--watch-absolute-filename watch))
>       :-callback 'file-notify--callback-kqueue))))
>
> assuming that `file-notify-descriptors` has some entries (enabling `global-auto-revert-mode` would add such entries).

So you must update the :-event slot.

Why do you call file-notify-handle-event yourself? It is not intended
for this use case.