rules_go icon indicating copy to clipboard operation
rules_go copied to clipboard

nogo broken with ".facts" errors in 0.50.0

Open aran opened this issue 1 year ago • 11 comments

What version of rules_go are you using?

0.50.0

What version of gazelle are you using?

0.38.0

What version of Bazel are you using?

7.3.1

Does this issue reproduce with the latest releases of all the above?

I think those are the latest

What operating system and processor architecture are you using?

macos/m2

Any other potentially useful information about your toolchain?

go_sdk 1.23.0

nogo set up:

load("@rules_go//go:def.bzl", "TOOLS_NOGO", "nogo")

nogo(
    name = "nogo",
    visibility = ["//visibility:public"],
    deps = TOOLS_NOGO,
)

What did you do?

In upgrading to 0.50.0, many go targets now fail with:

WARNING: Remote Cache: Expected output <...>/mycode.facts was not created locally.
WARNING: Remote Cache: Expected output <...>/mycode_lib.facts was not created locally.
ERROR: <mycode>/BUILD.bazel:3:11: output '<...>/mycode_lib.facts' was not created
ERROR: <mycode>/BUILD.bazel:10:10: output '<...>/mycode_lib.facts' was not created
ERROR: <mycode>/BUILD.bazel:10:10: Running nogo on <mycode>:mycode failed: not all outputs were created or valid
ERROR: <mycode>/BUILD.bazel:3:11: Running nogo on <mycode>:mycode_lib failed: not all outputs were created or valid

I tried clearing my `--disk_cache` target with no effect.

Removing `go_sdk.nogo(nogo = "...:nogo")` allows a successful build of all targets.


### What did you expect to see?

Successful build. 

### What did you see instead?

Errors referring to missing '.facts' files.

aran avatar Sep 02 '24 18:09 aran

Basic usage like that is covered by tests, so there must be something else about your targets that tickles the bug. Could you try to cut down one of the failing targets to the point that you can share it?

fmeum avatar Sep 02 '24 19:09 fmeum

https://github.com/aran/rules_go_4084 is small and has the issue for me. I also ran bazel clean --expunge to try it out. Just building with bazel build //..., it works without the nogo line in MODULE.bazel, and fails with the line present.

aran avatar Sep 02 '24 22:09 aran

I have no idea why there is no error message in this case, but when I commented out the last of the analyzers in TOOLS_NOGO as an attempt to bisect the problem, I saw this panic:

panic: any

goroutine 39 [running]:
golang.org/x/tools/go/ssa.forEachReachable.func1({0x104f06248, 0x14000126cc0}, 0x0?)
	external/gazelle~~go_deps~org_golang_x_tools/go/ssa/methods.go:269 +0x3e0
golang.org/x/tools/go/ssa.forEachReachable.func1({0x104f061d0, 0x140002adb00}, 0x10?)
	external/gazelle~~go_deps~org_golang_x_tools/go/ssa/methods.go:261 +0x4b8
golang.org/x/tools/go/ssa.forEachReachable.func1({0x104f06090, 0x14000175f10}, 0xc0?)
	external/gazelle~~go_deps~org_golang_x_tools/go/ssa/methods.go:208 +0xd4
golang.org/x/tools/go/ssa.forEachReachable.func1({0x104f061d0, 0x140002adbc0}, 0x70?)
	external/gazelle~~go_deps~org_golang_x_tools/go/ssa/methods.go:261 +0x4b8
golang.org/x/tools/go/ssa.forEachReachable.func1({0x104f06090, 0x140002c8070}, 0x40?)
	external/gazelle~~go_deps~org_golang_x_tools/go/ssa/methods.go:208 +0xd4
golang.org/x/tools/go/ssa.forEachReachable.func1({0x104f06158, 0x140002b6b40}, 0x50?)
	external/gazelle~~go_deps~org_golang_x_tools/go/ssa/methods.go:222 +0x160
golang.org/x/tools/go/ssa.forEachReachable.func1({0x104f061d0, 0x140002adc50}, 0x70?)
	external/gazelle~~go_deps~org_golang_x_tools/go/ssa/methods.go:261 +0x4b8
golang.org/x/tools/go/ssa.forEachReachable.func1({0x104f061a8, 0x140002b7070}, 0xb8?)
	external/gazelle~~go_deps~org_golang_x_tools/go/ssa/methods.go:208 +0xd4
golang.org/x/tools/go/ssa.forEachReachable(0x140004cadc8?, {0x104f061a8?, 0x140002b7070?}, 0x104deffe0?)
	external/gazelle~~go_deps~org_golang_x_tools/go/ssa/methods.go:272 +0x60
golang.org/x/tools/go/ssa.addRuntimeType(0x104f061a8?, {0x104f061a8?, 0x140002b7070?})
	external/gazelle~~go_deps~org_golang_x_tools/go/ssa/builder.go:2601 +0xe8
golang.org/x/tools/go/ssa.emitConv(0x140004c4000, {0x104f09178, 0x14000480540}, {0x104f06090, 0x14000174e00})
	external/gazelle~~go_deps~org_golang_x_tools/go/ssa/emit.go:250 +0x400
golang.org/x/tools/go/ssa.(*builder).emitCallArgs(0x1400001e550, 0x140004c4000, 0x140001d5680, 0x14000127900, {0x0?, 0x0, 0x78?})
	external/gazelle~~go_deps~org_golang_x_tools/go/ssa/builder.go:1044 +0x23c
golang.org/x/tools/go/ssa.(*builder).setCall(0x1400001e550, 0x140004c4000, 0x14000127900, 0x1400002a840)
	external/gazelle~~go_deps~org_golang_x_tools/go/ssa/builder.go:1089 +0x80
golang.org/x/tools/go/ssa.(*builder).expr0(0x1400001e550, 0x140004c4000, {0x104f068e8?, 0x14000127900}, {0x7, {0x104f06090, 0x14000174e70}, {0x0, 0x0}})
	external/gazelle~~go_deps~org_golang_x_tools/go/ssa/builder.go:666 +0x215c
golang.org/x/tools/go/ssa.(*builder).expr(0x1400001e550, 0x140004c4000, {0x104f068e8, 0x14000127900})
	external/gazelle~~go_deps~org_golang_x_tools/go/ssa/builder.go:585 +0x11c
golang.org/x/tools/go/ssa.(*builder).assign(0x1400001e550?, 0x140004c4000, {0x104f07298, 0x1400007c6f0}, {0x104f068e8?, 0x14000127900?}, 0x48?, 0x140004e3658)
	external/gazelle~~go_deps~org_golang_x_tools/go/ssa/builder.go:558 +0x2f8
golang.org/x/tools/go/ssa.(*builder).assignStmt(0x1400001e550, 0x140004c4000, {0x14000113ab0, 0x1, 0x1?}, {0x14000113ad0, 0x1, 0x19?}, 0x1)
	external/gazelle~~go_deps~org_golang_x_tools/go/ssa/builder.go:1167 +0x318
golang.org/x/tools/go/ssa.(*builder).stmt(0x1400001e550, 0x140004c4000, {0x104f06b28?, 0x14000127940?})
	external/gazelle~~go_deps~org_golang_x_tools/go/ssa/builder.go:2371 +0x8b4
golang.org/x/tools/go/ssa.(*builder).stmtList(...)
	external/gazelle~~go_deps~org_golang_x_tools/go/ssa/builder.go:910
golang.org/x/tools/go/ssa.(*builder).stmt(0x1400001e550, 0x140004c4000, {0x104f06a38?, 0x1400010b5c0?})
	external/gazelle~~go_deps~org_golang_x_tools/go/ssa/builder.go:2467 +0xbf0
golang.org/x/tools/go/ssa.(*builder).buildFromSyntax(0x1400001e550, 0x140004c4000)
	external/gazelle~~go_deps~org_golang_x_tools/go/ssa/builder.go:2579 +0x204
golang.org/x/tools/go/ssa.(*builder).buildFunction(0x104ebd501?, 0x140004c4000)
	external/gazelle~~go_deps~org_golang_x_tools/go/ssa/builder.go:2533 +0x110
golang.org/x/tools/go/ssa.(*builder).iterate(0x1400001e550)
	external/gazelle~~go_deps~org_golang_x_tools/go/ssa/builder.go:2521 +0x2c
golang.org/x/tools/go/ssa.(*Package).build(0x1400002a400)
	external/gazelle~~go_deps~org_golang_x_tools/go/ssa/builder.go:2650 +0xa4
sync.(*Once).doSlow(0x1400007e270?, 0x14000122e40?)
	GOROOT/src/sync/once.go:76 +0xf8
sync.(*Once).Do(...)
	GOROOT/src/sync/once.go:67
golang.org/x/tools/go/ssa.(*Package).Build(...)
	external/gazelle~~go_deps~org_golang_x_tools/go/ssa/builder.go:2639
golang.org/x/tools/go/analysis/passes/buildssa.run(0x1400007e1a0)
	external/gazelle~~go_deps~org_golang_x_tools/go/analysis/passes/buildssa/buildssa.go:59 +0x270
main.(*action).execOnce(0x1400011b360)
	external/rules_go~/go/tools/builders/nogo_main.go:376 +0x728
sync.(*Once).doSlow(0x0?, 0x0?)
	GOROOT/src/sync/once.go:76 +0xf8
sync.(*Once).Do(...)
	GOROOT/src/sync/once.go:67
main.(*action).exec(...)
	external/rules_go~/go/tools/builders/nogo_main.go:305
main.execAll.func1(0x0?)
	external/rules_go~/go/tools/builders/nogo_main.go:299 +0x6c
created by main.execAll in goroutine 1
	external/rules_go~/go/tools/builders/nogo_main.go:297 +0x4c

This makes me think that this is an issue in golang.org/x/tools and indeed, after bazel run @rules_go//go get golang.org/x/tools, the issue is gone.

@tyler-french We probably have to update golang.org/x/tools when we switch to Go 1.23.0 in CI.

fmeum avatar Sep 03 '24 22:09 fmeum

Thanks for looking. That's a great help. In case anyone else stumbles here, I can workaround with this addition to MODULE.bazel:

# TODO: Remove when https://github.com/bazelbuild/rules_go/issues/4084 is resolved 
go_deps.module(
    path = "golang.org/x/tools",
    # curl https://sum.golang.org/lookup/golang.org/x/[email protected]
    sum = "h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=",
    version = "v0.24.0",
)

and adding it to the go_deps:

use_repo(
    go_deps,
     ...
     "org_golang_x_tools",
     ...

aran avatar Sep 04 '24 20:09 aran

What work remains to be done here in order to fix this problem? It's hard to tell from reading the preceding comments whether there's a change required in this repository, or if we're waiting on a fix in an upstream dependency.

seh avatar Oct 22 '24 16:10 seh

It needs a bump of x/tools in go.mod (but nothing else). Since that repo is rather unstable, I don't want to force the update on everyone just yet. It's arguably the end user's duty to update and control the versions of these deps.

fmeum avatar Oct 22 '24 18:10 fmeum

Oh, does that mean that if my own go.mod file requires a new enough version of that x/tools module that I'd wind up fixing this for myself?

At present, my go.mod file declares a(n indirect) dependency at version 0.24.0.

seh avatar Oct 22 '24 19:10 seh

That should work if you are using Bzlmod and go_deps. If not, then your own go_repository would collide with the one defined as a dep of rules_go.

fmeum avatar Oct 22 '24 20:10 fmeum

I'm running into this as well and the workaround from @aran works for now, thanks for the snippet!

jbedard avatar Oct 29 '24 22:10 jbedard

Hi, I'm seeing this error as well, running rules_go 0.50, gazelle 0.39.1, Go 1.23.6. I am already using golang.org/x/tools 0.24.0, but upgrading it to the latest version 0.30.0 also doesn't seem to help. Same with upgrading rules_go, etc. I'm wondering how can I surface the error/panic message from nogo? This would probably be enough to make progress on finding the solution.

I've isolated the issue to one of our custom purpose-built analyzers, so there is no real upstream issue, but the lack of error messages will make it difficult to track down what the actual problem is.

EDIT: Never mind, I've resolved the issue: in our case I needed to update github.com/kisielk/errcheck to the latest version.

rickystewart avatar Feb 11 '25 20:02 rickystewart

It seems like this might be a case of an analyzer calling panic and that not being handled.

My anecdotal contribution here is that I was seeing a panic from honnef.co/go/tools/analysis/lint.ExhaustiveTypeSwitch. But the hard part was that the panic was only being captured in the .nogo.log file in the output_path. So if you see one of those

ERROR: <mycode>/BUILD.bazel:3:11: output '<...>/mycode_lib.facts' was not created

lines, you can see the panic if you

cat bazel-out/<configuration>/bin/<mycode>/mycode_lib.nogo.log

In any case, for the particular issue I was running into, updating honnef.co/go/tools to a newer version that supported the version of Go I was updating to was the fix. But this was only a fix because the issue was that the previously older version of honnef.co/go/tools wasn't aware of the types in newer versions, so its internal check that used honnef.co/go/tools/analysis/lint.ExhaustiveTypeSwitch in its analyzers was failing when one of the newer types showed up.

That also seems to align with some folks needing to update golang.org/x/tools, or github.com/kisielk/errcheck to address this on their end.

I don't know that updating dependencies is going to fix this for everyone. Since the problem seems to be that any analyzer can call panic and that causes the RunNogo action to fail before the outputs are created. There probably needs to be a recover in the right spot to handle these potential panics, make sure the outputs are created, and move panic'd output to wherever the normal analyzer output goes.

joneshf avatar Apr 28 '25 03:04 joneshf

I think that this is fixed by https://github.com/bazel-contrib/rules_go/commit/76e2cb9305461a2e7fbabc3946c97a4a1b2c54ae. Please speak up if you still see this with that commit.

fmeum avatar Jul 31 '25 17:07 fmeum