This is a corrected and enhanced report of #3081.
In ivy-done, when REQUIRE-MATCH is a function, Ivy calls it with zero arguments. However, the Emacs completing-read specification states that a function passed as REQUIRE-MATCH should be called with the input as the argument.
From the completing-read docstring:
REQUIRE-MATCH can take the following values:
...
- a function, which will be called with the input as the argument. If the function returns a non-nil value, the minibuffer is exited with that argument as the value.
This causes a wrong-number-of-arguments error when packages (e.g., Magit) correctly pass a 1-arity function as REQUIRE-MATCH.
Steps to Reproduce
- Enable
ivy-mode
- Invoke a command that passes a function as
REQUIRE-MATCH to completing-read. For example, in Magit: magit-status → b c (branch and checkout)
- Type a branch name and press
RET
Backtrace
(wrong-number-of-arguments (1 . 1) 0)
#f(compiled-function (choice) #<bytecode 0x1bef4b8e62911372>)()
ivy-done()
ivy-alt-done(nil)
funcall-interactively(ivy-alt-done nil)
call-interactively(ivy-alt-done nil nil)
command-execute(ivy-alt-done)
read-from-minibuffer("Name for new branch: " ...)
ivy-read("Name for new branch: " ... :require-match #f(compiled-function (choice) ...) ...)
ivy-completing-read("Name for new branch: " ... nil #f(compiled-function (choice) ...) ...)
completing-read("Name for new branch: " ... nil #f(compiled-function (choice) ...) ...)
magit-completing-read("Name for new branch" nil nil #f(compiled-function (choice) ...))
magit-branch--read-name("Name for new branch" "origin/master")
magit-branch-read-args("Create and checkout branch")
Root Cause
In ivy-done (ivy.el), the relevant cond clause:
((or (and (memq (ivy-state-collection ivy-last)
'(read-file-name-internal internal-complete-buffer))
(eq confirm-nonexistent-file-or-buffer t))
(and (functionp require-match)
(setq require-match (funcall require-match)))) ;; ← BUG: 0 args
(funcall require-match) is called with no arguments, but per the completing-read contract, it should be called with the current input.
Suggested Fix
;; Before (broken):
(funcall require-match)
;; After (correct per completing-read spec):
(funcall require-match ivy-text) ; or some other valid argument
Environment
- Emacs: 30.2 (tested both TUI and GUI)
- Ivy/Swiper/Counsel: latest
- Triggered by: Magit (latest)
- OS: Bug experienced and fix tested on macOS, Redhat-based Linux, and WSL2 Ubuntu
This is a corrected and enhanced report of #3081.
In
ivy-done, whenREQUIRE-MATCHis a function, Ivy calls it with zero arguments. However, the Emacscompleting-readspecification states that a function passed asREQUIRE-MATCHshould be called with the input as the argument.From the
completing-readdocstring:This causes a
wrong-number-of-argumentserror when packages (e.g., Magit) correctly pass a 1-arity function asREQUIRE-MATCH.Steps to Reproduce
ivy-modeREQUIRE-MATCHtocompleting-read. For example, in Magit:magit-status→b c(branch and checkout)RETBacktrace
Root Cause
In
ivy-done(ivy.el), the relevantcondclause:(funcall require-match)is called with no arguments, but per thecompleting-readcontract, it should be called with the current input.Suggested Fix
Environment