Subject: wrong irritant for 'wrong number of arguments' exception inside modules

From: afjytggm afjytggm <[email-masked]>
Date: Mon, 1 Sep 2025 17:56:32 -0400

Hey, so first off, I guess just for what my expected behavior is here,
here's an example of calling a function with the wrong number of arguments
under an exception handler. And you can see that the irritant that it gives
back points to the function where you called the wrong number of arguments,
right?

(use-modules (rnrs conditions))

(define (func s)
  1)

(define (main)
  (func))

(define (start-main)
  (with-exception-handler
    (lambda (c . more)
      (display "Caught an exception!\n")
      (when (message-condition? c)
        (display c))
      (newline))
    (lambda ()
      (main))))

(start-main)

(ins)moke@palsy:~/projects/2025/6-guile/c-except/just-except$ guile -q
except.scm
Caught an exception!
#<&compound-exception components: (#<&assertion-failure> #<&origin origin:
#f> #<&message message: "Wrong number of arguments to ~A"> #<&irritants
irritants: (#<procedure func (s)>)> #<&exception-with-kind-and-args kind:
wrong-number-of-args args: (#f "Wrong number of arguments to ~A"
(#<procedure func (s)>) #f)>)>
... then the backtrace

but in particular:
#<&irritants irritants: (#<procedure func (s)>)>

 So here I do the same thing except I do it inside of a module.

(define-module (except)
               #:export (
                         start-main
                         ))
(use-modules (rnrs conditions))

(define (func s)
  1)

(define (main)
    (func)
    (display "test\n"))

(define (start-main)
  (with-exception-handler
    (lambda (c . more)
      (display "Caught an exception!\n")
      (when (message-condition? c)
        (display c))

      (newline))
    (lambda ()
      (main))))

with a separate runner.scm:
(set! %load-path (cons "." %load-path))
(use-modules (except))
(start-main)

now:
in 3.0.8:
(ins)moke@palsy:~/projects/2025/6-guile/c-except$ guile -q runner.scm
;;; note: auto-compilation is enabled, set GUILE_AUTO_COMPILE=0
;;;       or pass the --no-auto-compile argument to disable.
;;; compiling /home/moke/projects/2025/6-guile/c-except/runner.scm
;;; WARNING: compilation of
/home/moke/projects/2025/6-guile/c-except/runner.scm failed:
;;; no code for module (except)
;;; note: source file ./except.scm
;;;       newer than compiled
/home/moke/.cache/guile/ccache/3.0-LE-8-4.6/home/moke/projects/2025/6-guile/c-except/except.scm.go
;;; compiling ./except.scm
;;; except.scm:12:2: warning: wrong number of arguments to `func'
;;; compiled
/home/moke/.cache/guile/ccache/3.0-LE-8-4.6/home/moke/projects/2025/6-guile/c-except/except.scm.go
Caught an exception!
#<&compound-exception components: (#<&assertion-failure> #<&origin origin:
#f> #<&message message: "Wrong number of arguments to ~A"> #<&irritants
irritants: ((Segmentation fault

the segfault goes away in the github 3.0.10.215-020d8, but the irritant is
still not the correct thing.
Caught an exception!
#<&compound-exception components: (#<&assertion-failure> #<&origin origin:
#f> #<&message message: "Wrong number of arguments to ~A"> #<&irritants
irritants: (#<procedure 7f7b182ae3e0 at except.scm:22:4 ()>)>
#<&exception-with-kind-and-args kind: wrong-number-of-args args: (#f "Wrong
number of arguments to ~A" (#<procedure 7f7b182ae3e0 at except.scm:22:4
()>) #f)>)>

it now points to the top of the lambda of the exception handler:
===============================================
      (display "Caught an exception!\n")
      (when (message-condition? c)
        (display c))

      (newline))
    (lambda ()  ;;   <==== points right here
      (main))))
===============================================

you can set it to the return of whatever is above the line like this:
(define-module (except)
               #:export (
                         start-main
                         ))
(use-modules (rnrs conditions))

(define (func s)
  1)

(define (main)
  (open "test" (logior O_CREAT O_WRONLY))       ;; new stuff added here
<====
  (func)
  (display "test\n"))

(define (start-main)
  (with-exception-handler
    (lambda (c . more)
      (display "Caught an exception!\n")
      (when (message-condition? c)
        (display c))

      (newline))
    (lambda ()
      (main))))

here i just added an open above the bad func call, we can now see its
return value
is the irritant:
Caught an exception!
#<&compound-exception components: (#<&assertion-failure> #<&origin origin:
#f> #<&message message: "Wrong number of arguments to ~A"> #<&irritants
irritants: (#<output: test 9>)> #<&exception-with-kind-and-args kind:
wrong-number-of-args args: (#f "Wrong number of arguments to ~A" (#<output:
test 9>) #f)>)>

same behavior in both versions, debian and github head

Here's some system details:

(ins)moke@palsy:~/projects/2025/guile/build-aux$ ./config.guess
x86_64-pc-linux-gnu
I'm using debian bookworm. Here's the guile in it:
(ins)moke@palsy:~/projects/2025/6-guile/c-except$ dpkg -l | grep guile
ii  guile-3.0                                                   3.0.8-2
                        amd64        GNU extension language and Scheme
interpreter
ii  guile-3.0-dev                                               3.0.8-2
                        amd64        Development files for Guile 3.0
ii  guile-3.0-doc                                               3.0.8-2
                        all          Documentation for Guile 3.0
ii  guile-3.0-libs:amd64                                        3.0.8-2
                        amd64        Core Guile libraries

Hope that's enough info. I've attached a copy of the segfaulting version
for 3.0.8 in the tar.