Typed rules don't work as expected
Describe the bug
The following rules don't work as expected:
context-keys-typeerrorfmodifies-value-receiverrange-val-addressstring-of-inttime-equaltime-namingunexported-returnunhandled-errorvar-declaration
To Reproduce
cd /tmp
git clone --branch revive https://github.com/ldez/fiber.git
cd fiber
# version 1.7.0 (I used the official binary)
revive --version
# Output: 24
revive -config=revive.toml ./... | wc -l
# Output: 3
GOROOT= revive -config=revive.toml ./... | wc -l
[rule.unhandled-error]
Expected behavior
I expect the rules to be less dependent on the environment and the compilation flags.
Logs
NA
Desktop (please complete the following information):
- OS: Linux
- go 1.24
Additional context
The problem relates to file.Pkg.TypeCheck(): the default importer uses GOROOT and GOPATH.
If you log the error returns by file.Pkg.TypeCheck(), you can see what happened.
Note, go env GOROOT always returns a value even if the env var is not set.
For example, GitHub Action runners don't have an explicit env var GOROOT.
The problem is increased if the binary is built with -trimpath.
~~For now, I haven't found a way to reproduce the same environment locally as GitHub Action runners, but I'm using an SSH connection to a runner to test it.~~
runner@fv-az1337-715:~/work/fiber/fiber$ go version
go version go1.24.1 linux/amd64
runner@fv-az1337-715:~/work/fiber/fiber$
runner@fv-az1337-715:~/work/fiber/fiber$ env | grep GOROOT
GOROOT_1_21_X64=/opt/hostedtoolcache/go/1.21.13/x64
GOROOT_1_23_X64=/opt/hostedtoolcache/go/1.23.7/x64
GOROOT_1_22_X64=/opt/hostedtoolcache/go/1.22.12/x64
runner@fv-az1337-715:~/work/fiber/fiber$
runner@fv-az1337-715:~/work/fiber/fiber$ go env GOROOT
/opt/hostedtoolcache/go/1.24.1/x64
runner@fv-az1337-715:~/work/fiber/fiber$
runner@fv-az1337-715:~/work/fiber/fiber$ cd /tmp
runner@fv-az1337-715:~/work/fiber/fiber$ git clone -q --branch v1.7.0 https://github.com/mgechev/revive.git && cd revive
runner@fv-az1337-715:~/work/fiber/fiber$
runner@fv-az1337-715:/tmp/revive$ go build -trimpath -o revive-trim .; go build -o revive-notrim .
...
runner@fv-az1337-715:/tmp/revive$ cd ~/work/fiber/fiber
runner@fv-az1337-715:~/work/fiber/fiber$ /tmp/revive/revive-notrim -config=revive.toml ./... | wc -l
24
runner@fv-az1337-715:~/work/fiber/fiber$ /tmp/revive/revive-trim -config=revive.toml ./... | wc -l
3
https://github.com/ldez/fiber/actions/runs/13937713921/job/39008703769
You can fork my branch https://github.com/ldez/fiber/tree/revive if you need it, the environment is already prepared (with SSH debug).
EDIT: I found a way to reproduce outside GitHub Action runners.
$ docker run --rm -it golang:1.24-alpine sh
/go # apk add -q git
/go # go version
go version go1.24.1 linux/amd64
/go # env | grep GOROOT
/go # env | grep GOPATH
GOPATH=/go
/go # go env GOROOT
/usr/local/go
/go # go env GOPATH
/go
/go # cd /tmp
/tmp # git clone -q --branch revive https://github.com/ldez/fiber.git
/tmp # git clone -q --branch v1.7.0 https://github.com/mgechev/revive.git
...
/tmp # cd revive
/tmp/revive # go build -trimpath -o revive-trim .; go build -o revive-notrim .
...
/tmp/revive # cd /tmp/fiber
/tmp/fiber # /tmp/revive/revive-notrim -config=revive.toml ./... | wc -l
24
/tmp/fiber # /tmp/revive/revive-trim -config=revive.toml ./... | wc -l
3
/tmp/fiber #
Just an additional note: don't be fooled by revive-notrim and its 24 reports, the problem is here too.
$ /tmp/revive/revive-notrim -config=revive.toml ./...
TypeCheck middleware/skip/skip.go:4:2: could not import github.com/gofiber/fiber/v3 (can't find import: "github.com/gofiber/fiber/v3": cannot find package "github.com/gofiber/fiber/v3" in any of:
/usr/local/go/src/github.com/gofiber/fiber/v3 (from $GOROOT)
/go/src/github.com/gofiber/fiber/v3 (from $GOPATH))
TypeCheck middleware/earlydata/earlydata.go:4:2: could not import github.com/gofiber/fiber/v3 (can't find import: "github.com/gofiber/fiber/v3": cannot find package "github.com/gofiber/fiber/v3" in any of:
/usr/local/go/src/github.com/gofiber/fiber/v3 (from $GOROOT)
/go/src/github.com/gofiber/fiber/v3 (from $GOPATH))
TypeCheck middleware/idempotency/config.go:8:2: could not import github.com/gofiber/fiber/v3 (can't find import: "github.com/gofiber/fiber/v3": cannot find package "github.com/gofiber/fiber/v3" in any of:
/usr/local/go/src/github.com/gofiber/fiber/v3 (from $GOROOT)
/go/src/github.com/gofiber/fiber/v3 (from $GOPATH))
TypeCheck internal/memory/memory.go:9:2: could not import github.com/gofiber/utils/v2 (can't find import: "github.com/gofiber/utils/v2": cannot find package "github.com/gofiber/utils/v2" in any of:
/usr/local/go/src/github.com/gofiber/utils/v2 (from $GOROOT)
/go/src/github.com/gofiber/utils/v2 (from $GOPATH))
TypeCheck middleware/recover/recover.go:8:2: could not import github.com/gofiber/fiber/v3 (can't find import: "github.com/gofiber/fiber/v3": cannot find package "github.com/gofiber/fiber/v3" in any of:
/usr/local/go/src/github.com/gofiber/fiber/v3 (from $GOROOT)
/go/src/github.com/gofiber/fiber/v3 (from $GOPATH))
TypeCheck middleware/helmet/config.go:4:2: could not import github.com/gofiber/fiber/v3 (can't find import: "github.com/gofiber/fiber/v3": cannot find package "github.com/gofiber/fiber/v3" in any of:
/usr/local/go/src/github.com/gofiber/fiber/v3 (from $GOROOT)
/go/src/github.com/gofiber/fiber/v3 (from $GOPATH))
TypeCheck middleware/timeout/timeout.go:8:2: could not import github.com/gofiber/fiber/v3 (can't find import: "github.com/gofiber/fiber/v3": cannot find package "github.com/gofiber/fiber/v3" in any of:
/usr/local/go/src/github.com/gofiber/fiber/v3 (from $GOROOT)
/go/src/github.com/gofiber/fiber/v3 (from $GOPATH))
TypeCheck addon/retry/exponential_backoff_test.go:8:2: could not import github.com/stretchr/testify/require (can't find import: "github.com/stretchr/testify/require": cannot find package "github.com/stretchr/testify/require" in any of:
/usr/local/go/src/github.com/stretchr/testify/require (from $GOROOT)
/go/src/github.com/stretchr/testify/require (from $GOPATH))
TypeCheck middleware/encryptcookie/encryptcookie.go:4:2: could not import github.com/gofiber/fiber/v3 (can't find import: "github.com/gofiber/fiber/v3": cannot find package "github.com/gofiber/fiber/v3" in any of:
/usr/local/go/src/github.com/gofiber/fiber/v3 (from $GOROOT)
/go/src/github.com/gofiber/fiber/v3 (from $GOPATH))
TypeCheck middleware/etag/config.go:4:2: could not import github.com/gofiber/fiber/v3 (can't find import: "github.com/gofiber/fiber/v3": cannot find package "github.com/gofiber/fiber/v3" in any of:
/usr/local/go/src/github.com/gofiber/fiber/v3 (from $GOROOT)
/go/src/github.com/gofiber/fiber/v3 (from $GOPATH))
TypeCheck internal/storage/memory/memory_test.go:7:2: could not import github.com/stretchr/testify/require (can't find import: "github.com/stretchr/testify/require": cannot find package "github.com/stretchr/testify/require" in any of:
/usr/local/go/src/github.com/stretchr/testify/require (from $GOROOT)
/go/src/github.com/stretchr/testify/require (from $GOPATH))
TypeCheck middleware/envvar/envvar.go:7:2: could not import github.com/gofiber/fiber/v3 (can't find import: "github.com/gofiber/fiber/v3": cannot find package "github.com/gofiber/fiber/v3" in any of:
/usr/local/go/src/github.com/gofiber/fiber/v3 (from $GOROOT)
/go/src/github.com/gofiber/fiber/v3 (from $GOPATH))
TypeCheck middleware/redirect/config.go:6:2: could not import github.com/gofiber/fiber/v3 (can't find import: "github.com/gofiber/fiber/v3": cannot find package "github.com/gofiber/fiber/v3" in any of:
/usr/local/go/src/github.com/gofiber/fiber/v3 (from $GOROOT)
/go/src/github.com/gofiber/fiber/v3 (from $GOPATH))
TypeCheck middleware/cache/cache.go:13:2: could not import github.com/gofiber/fiber/v3 (can't find import: "github.com/gofiber/fiber/v3": cannot find package "github.com/gofiber/fiber/v3" in any of:
/usr/local/go/src/github.com/gofiber/fiber/v3 (from $GOROOT)
/go/src/github.com/gofiber/fiber/v3 (from $GOPATH))
TypeCheck middleware/favicon/favicon.go:9:2: could not import github.com/gofiber/fiber/v3 (can't find import: "github.com/gofiber/fiber/v3": cannot find package "github.com/gofiber/fiber/v3" in any of:
/usr/local/go/src/github.com/gofiber/fiber/v3 (from $GOROOT)
/go/src/github.com/gofiber/fiber/v3 (from $GOPATH))
TypeCheck middleware/basicauth/basicauth.go:7:2: could not import github.com/gofiber/fiber/v3 (can't find import: "github.com/gofiber/fiber/v3": cannot find package "github.com/gofiber/fiber/v3" in any of:
/usr/local/go/src/github.com/gofiber/fiber/v3 (from $GOROOT)
/go/src/github.com/gofiber/fiber/v3 (from $GOPATH))
TypeCheck log/default_test.go:10:2: could not import github.com/stretchr/testify/require (can't find import: "github.com/stretchr/testify/require": cannot find package "github.com/stretchr/testify/require" in any of:
/usr/local/go/src/github.com/stretchr/testify/require (from $GOROOT)
/go/src/github.com/stretchr/testify/require (from $GOPATH))
TypeCheck middleware/requestid/config.go:4:2: could not import github.com/gofiber/fiber/v3 (can't find import: "github.com/gofiber/fiber/v3": cannot find package "github.com/gofiber/fiber/v3" in any of:
/usr/local/go/src/github.com/gofiber/fiber/v3 (from $GOROOT)
/go/src/github.com/gofiber/fiber/v3 (from $GOPATH))
TypeCheck middleware/proxy/config.go:7:2: could not import github.com/gofiber/fiber/v3 (can't find import: "github.com/gofiber/fiber/v3": cannot find package "github.com/gofiber/fiber/v3" in any of:
/usr/local/go/src/github.com/gofiber/fiber/v3 (from $GOROOT)
/go/src/github.com/gofiber/fiber/v3 (from $GOPATH))
TypeCheck middleware/keyauth/keyauth.go:11:2: could not import github.com/gofiber/fiber/v3 (can't find import: "github.com/gofiber/fiber/v3": cannot find package "github.com/gofiber/fiber/v3" in any of:
/usr/local/go/src/github.com/gofiber/fiber/v3 (from $GOROOT)
/go/src/github.com/gofiber/fiber/v3 (from $GOPATH))
TypeCheck middleware/rewrite/rewrite.go:8:2: could not import github.com/gofiber/fiber/v3 (can't find import: "github.com/gofiber/fiber/v3": cannot find package "github.com/gofiber/fiber/v3" in any of:
/usr/local/go/src/github.com/gofiber/fiber/v3 (from $GOROOT)
/go/src/github.com/gofiber/fiber/v3 (from $GOPATH))
TypeCheck middleware/healthcheck/config.go:4:2: could not import github.com/gofiber/fiber/v3 (can't find import: "github.com/gofiber/fiber/v3": cannot find package "github.com/gofiber/fiber/v3" in any of:
/usr/local/go/src/github.com/gofiber/fiber/v3 (from $GOROOT)
/go/src/github.com/gofiber/fiber/v3 (from $GOPATH))
TypeCheck middleware/expvar/expvar.go:6:2: could not import github.com/gofiber/fiber/v3 (can't find import: "github.com/gofiber/fiber/v3": cannot find package "github.com/gofiber/fiber/v3" in any of:
/usr/local/go/src/github.com/gofiber/fiber/v3 (from $GOROOT)
/go/src/github.com/gofiber/fiber/v3 (from $GOPATH))
TypeCheck middleware/compress/compress.go:4:2: could not import github.com/gofiber/fiber/v3 (can't find import: "github.com/gofiber/fiber/v3": cannot find package "github.com/gofiber/fiber/v3" in any of:
/usr/local/go/src/github.com/gofiber/fiber/v3 (from $GOROOT)
/go/src/github.com/gofiber/fiber/v3 (from $GOPATH))
TypeCheck middleware/limiter/limiter.go:4:2: could not import github.com/gofiber/fiber/v3 (can't find import: "github.com/gofiber/fiber/v3": cannot find package "github.com/gofiber/fiber/v3" in any of:
/usr/local/go/src/github.com/gofiber/fiber/v3 (from $GOROOT)
/go/src/github.com/gofiber/fiber/v3 (from $GOPATH))
TypeCheck middleware/static/config.go:7:2: could not import github.com/gofiber/fiber/v3 (can't find import: "github.com/gofiber/fiber/v3": cannot find package "github.com/gofiber/fiber/v3" in any of:
/usr/local/go/src/github.com/gofiber/fiber/v3 (from $GOROOT)
/go/src/github.com/gofiber/fiber/v3 (from $GOPATH))
TypeCheck middleware/cors/config.go:4:2: could not import github.com/gofiber/fiber/v3 (can't find import: "github.com/gofiber/fiber/v3": cannot find package "github.com/gofiber/fiber/v3" in any of:
/usr/local/go/src/github.com/gofiber/fiber/v3 (from $GOROOT)
/go/src/github.com/gofiber/fiber/v3 (from $GOPATH))
TypeCheck middleware/adaptor/adaptor.go:11:2: could not import github.com/gofiber/fiber/v3 (can't find import: "github.com/gofiber/fiber/v3": cannot find package "github.com/gofiber/fiber/v3" in any of:
/usr/local/go/src/github.com/gofiber/fiber/v3 (from $GOROOT)
/go/src/github.com/gofiber/fiber/v3 (from $GOPATH))
TypeCheck middleware/pprof/config.go:4:2: could not import github.com/gofiber/fiber/v3 (can't find import: "github.com/gofiber/fiber/v3": cannot find package "github.com/gofiber/fiber/v3" in any of:
/usr/local/go/src/github.com/gofiber/fiber/v3 (from $GOROOT)
/go/src/github.com/gofiber/fiber/v3 (from $GOPATH))
TypeCheck middleware/csrf/config.go:8:2: could not import github.com/gofiber/fiber/v3 (can't find import: "github.com/gofiber/fiber/v3": cannot find package "github.com/gofiber/fiber/v3" in any of:
/usr/local/go/src/github.com/gofiber/fiber/v3 (from $GOROOT)
/go/src/github.com/gofiber/fiber/v3 (from $GOPATH))
TypeCheck middleware/logger/template_chain.go:7:2: could not import github.com/gofiber/utils/v2 (can't find import: "github.com/gofiber/utils/v2": cannot find package "github.com/gofiber/utils/v2" in any of:
/usr/local/go/src/github.com/gofiber/utils/v2 (from $GOROOT)
/go/src/github.com/gofiber/utils/v2 (from $GOPATH))
TypeCheck binder/cbor.go:4:2: could not import github.com/gofiber/utils/v2 (can't find import: "github.com/gofiber/utils/v2": cannot find package "github.com/gofiber/utils/v2" in any of:
/usr/local/go/src/github.com/gofiber/utils/v2 (from $GOROOT)
/go/src/github.com/gofiber/utils/v2 (from $GOPATH))
TypeCheck client/hooks.go:14:2: could not import github.com/gofiber/utils/v2 (can't find import: "github.com/gofiber/utils/v2": cannot find package "github.com/gofiber/utils/v2" in any of:
/usr/local/go/src/github.com/gofiber/utils/v2 (from $GOROOT)
/go/src/github.com/gofiber/utils/v2 (from $GOPATH))
TypeCheck middleware/session/session.go:10:2: could not import github.com/gofiber/fiber/v3 (can't find import: "github.com/gofiber/fiber/v3": cannot find package "github.com/gofiber/fiber/v3" in any of:
/usr/local/go/src/github.com/gofiber/fiber/v3 (from $GOROOT)
/go/src/github.com/gofiber/fiber/v3 (from $GOPATH))
TypeCheck error_test.go:8:2: could not import github.com/gofiber/schema (can't find import: "github.com/gofiber/schema": cannot find package "github.com/gofiber/schema" in any of:
/usr/local/go/src/github.com/gofiber/schema (from $GOROOT)
/go/src/github.com/gofiber/schema (from $GOPATH))
middleware/adaptor/adaptor_test.go:70:3: Unhandled error in call to function fmt.Fprintf
listen.go:369:2: Unhandled error in call to function fmt.Fprintf
listen.go:370:2: Unhandled error in call to function fmt.Fprintf
listen.go:373:3: Unhandled error in call to function fmt.Fprintf
listen.go:377:3: Unhandled error in call to function fmt.Fprintf
listen.go:383:3: Unhandled error in call to function fmt.Fprintf
listen.go:386:2: Unhandled error in call to function fmt.Fprintf
listen.go:391:3: Unhandled error in call to function fmt.Fprintf
listen.go:393:3: Unhandled error in call to function fmt.Fprintf
listen.go:396:2: Unhandled error in call to function fmt.Fprintf
listen.go:397:2: Unhandled error in call to function fmt.Fprintf
listen.go:408:3: Unhandled error in call to function fmt.Fprintf
listen.go:421:5: Unhandled error in call to function fmt.Fprintf
listen.go:423:6: Unhandled error in call to function fmt.Fprintf
listen.go:426:4: Unhandled error in call to function fmt.Fprintf
listen.go:431:2: Unhandled error in call to function fmt.Fprintf
listen.go:473:2: Unhandled error in call to function fmt.Fprintf
listen.go:474:2: Unhandled error in call to function fmt.Fprintf
listen.go:477:3: Unhandled error in call to function fmt.Fprintf
helpers_test.go:569:2: Unhandled error in call to function fiber.testConn.Close
app.go:1027:4: Unhandled error in call to function fiber.testConn.Close
ctx_test.go:4580:3: Unhandled error in call to function bufio.Writer.WriteString
ctx_test.go:4587:4: Unhandled error in call to function fmt.Fprintf
I think my issue was unclear about the scope of the problem.
The problem has always happened, and it's been here for a long time, but it was previously hidden by another bug that has been fixed by #1237.
@ldez could you tell us if the fix you made with #1308 for #1306 also fixed this one?
- #1308
- #1306
Thanks
It doesn't fix this one.
Thanks for the confirmation
I started working on this.
It's indeed far from being fun 😅
@ldez analysis is great. The issue is indeed the fact the GOROOT is empty in the compiled binary.
Using imports.ForCompiler helps a bit, but there is still a problem with GOROOT being empty.
So here, I would say the solution might be around writing our own importer, or maybe simply use our importer.Lookup function with imports.ForCompiler
I might be likely wrong, but there is a very small chance that I will end with opening an issue on Go project to fix this strange behavior for everyone.
I had never played with -trimpath, I end up discovering a new world, and having a lot of fun.
Stay tuned.
I might be likely wrong, but there is a very small chance that I will end with opening an issue on Go project to fix this strange behavior for everyone.
IIRC this is all intended. GOROOT itself is deprecated, documented as poorly behaved (https://pkg.go.dev/runtime#GOROOT). Calling ForCompiler with nil is also deprected (https://pkg.go.dev/go/importer#ForCompiler:~:text=Deprecated%3A%20If%20lookup%20is%20nil%2C%20for%20backwards%2Dcompatibility%2C%20the%20importer%20will%20attempt%20to%20resolve%20imports%20in%20the%20%24GOPATH%20workspace).
Is there a reason to use these APIs directly, rather than use go/packages, or even https://pkg.go.dev/golang.org/x/[email protected]/go/analysis/checker?
One thing that surprised me by working on this issue. And it might obvious for you guys like @chavacava @alexandear @denisvmedia and Ludovic (previously pingued)
No matter if we are using revive with or without -trimpath, revive results depends on the Go sources that locally available on the machine where revive is launched.
So result may varies :
- previously compiled revive binary is launched on a machine where Go sources are not available (unlikely to happen)
- revive was compiled with a different version than the Go available on the machine
- revive was compiled with the same Go version as the code it analyze
Also, I was surprised to see there is no real good solution to get the GOROOT without doing this
go env GOROOT (which depends on having go binary installed locally)
It reminded me what Ludovic did with grignotin
I might be likely wrong, but there is a very small chance that I will end with opening an issue on Go project to fix this strange behavior for everyone.
IIRC this is all intended. GOROOT itself is deprecated, documented as poorly behaved (https://pkg.go.dev/runtime#GOROOT). Calling
ForCompilerwithnilis also deprected (https://pkg.go.dev/go/importer#ForCompiler:~:text=Deprecated%3A%20If%20lookup%20is%20nil%2C%20for%20backwards%2Dcompatibility%2C%20the%20importer%20will%20attempt%20to%20resolve%20imports%20in%20the%20%24GOPATH%20workspace).
Yes, I noticed all this by doing iterative discovery.
Is there a reason to use these APIs directly, rather than use
go/packages, or even https://pkg.go.dev/golang.org/x/[email protected]/go/analysis/checker?
I'm happy you are somehow confirming me there is something else that exists to do it. Because with the current code, I see no real hope, and it would lead to do some hacks, or will require to wait for a bug to be resolved in Go code (this is unlikely to happen I think)
I was expecting someone to come here and say "but why aren't you using …"
So thank you @jakebailey
I will have a look in that direction. It's true that I started from the code, and didn't try to think about what the code is doing and how could it be achieved.
Anyway, I learned some parts of the Go stack that I have never met, so it's still a good thing, because I learned things today.
wait for a bug to be resolved in Go code
not to derail this but... which bug?
wait for a bug to be resolved in Go code
not to derail this but... which bug?
As I said in my previous comment.
I might be likely wrong, but there is a very small chance that I will end with opening an issue on Go project to fix this strange behavior for everyone.
I might create one with the information I gathered after I will triple check there is a bug and that something happened to make it appears in revive because of a change I noticed in Go standard library.
So it's better to consider there is no real bug, and I still have to figure how stuffs work and how I should use them
Type-checking implementation in revive is hopeless obsolete. It was okay at the beginning but after GOROOT deprecation it never catch up since then. Instability (at least 2 bad documented and somewhat chaotic rewrites) of package-related libraries in the std lib didn't help either.
I think go/analysis/checker is the way to go. It will require some deep refactoring in revive (I've started that refactoring twice in the past... but with no luck)
which bug?
As I said in my previous comment.
I asked because, reading the previous comment before asking, I couldn't figure out what might be the go issue, but I can wait.