#1717·yaegi

Incorrect stack trace line numbering on runtime error with imported types

Author: SolarLuneCreated Mar 30, 2026Updated Mar 30, 2026

The following program sample.go triggers an unexpected result

go
package main

import (
	"reflect"

	"github.com/traefik/yaegi/interp"
)

type TestInterface interface {
	AFunc()
}

type Test struct{}

func (t *Test) AFunc() {}

func main() {

	exe := interp.New(interp.Options{})

	exe.Use(interp.Exports{
		"exe/exe": map[string]reflect.Value{
			"TestInterface": reflect.ValueOf((*TestInterface)(nil)),
			"Test":          reflect.ValueOf((*Test)(nil)),
		},
	})

	exe.Eval(`
	package main 

	import "exe"

	type Test struct {}
	
	func (t Test) AFunc() {}

	func main() {
		println("main!")
		t()
	}

	func t() {

		println("t")
		var a exe.TestInterface
		a.AFunc() // This is the problematic line, but it's not pointed to

		var b exe.TestInterface = &exe.Test{}
		b.AFunc()
		println("a")
	}
		`)

}

Expected result

bash
main!
t
19:3: panic: main.t(...)
11:3: panic: main.main(...)

Got

bash
main!
t
17:3: panic: main.t(...)
11:3: panic: main.main(...)

Yaegi Version

fcb76d1

Additional Notes

This is a bug that appears when getting a runtime error (for example, a nil-pointer exception) and Yaegi outputs a stack trace as to the bug's location.

Instead of it being the line of the offending statement, it's the beginning of the function that contains the offending statement. I believe this has to do with the runCfg() function in interp/run.go here:

https://github.com/traefik/yaegi/blob/master/interp/run.go#L205

Firstly, I believe the first line, var exec bltn, is never assigned to throughout the function, which makes getting its ownership incorrect. In addition, originalExecNode() is not working properly either, as I think the line that determines original execution (?), here:

https://github.com/traefik/yaegi/blob/master/interp/run.go#L159

seems to test if the built-in function being executed (bltn) is the same type as the offending function, rather than if it's the same function exactly...? Like, it's comparing pointers for the function values themselves, which point to one of a series of functions, so, another line with the same kind of function in the source would trigger this "get original node" code, I think.

I started working on resolving this, but I need some help figuring out exactly what to do, since I'm not super familiar with AST tree traversal and interpreters.

EDIT: Updated the example with a better one.