-
Notifications
You must be signed in to change notification settings - Fork 617
Description
Contributing guidelines
- I've read the contributing guidelines and wholeheartedly agree
I've found a bug and checked that ...
- ... the documentation does not mention anything about my problem
- ... there are no open or closed issues that are related to my problem
Description
Using a typed variable which has no default value and no provided value will panic in at least two scenarios when being used as build args. My original scenario was using it in a ternary operation, e.g. FOO = FOO == null ? "bar" : FOO. While coming up with a minimal reproduction, I found that a simple FOO = FOO will panic as well, though with a slightly different call stack. This only applies to typed variables.
Given that this is specific to typed variables, I'm assuming the issue is directly related to my previous contributions in this area and will look into it (feel free to assign to me). Thus, I'm going to skimp on areas of this report as they are likely irrelevant. (If it ends up being something totally different, I'll add more details at that point.)
Expected behaviour
A panic should not occur. Even if there's some technicality behind why my examples are actually invalid, it should result in a user-facing error message.
Actual behaviour
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x7fcba1]
Buildx version
github.com/docker/buildx v0.29.1 a32761a
Docker info
Builders list
NAME/NODE DRIVER/ENDPOINT STATUS BUILDKIT PLATFORMS
buildkit-dev docker-container
\_ buildkit-dev0 \_ unix:///var/run/docker.sock inactive
foo docker-container
\_ foo0 \_ unix:///var/run/docker.sock running v0.24.0 linux/amd64 (+4), linux/arm64, linux/arm (+2), linux/ppc64le, (7 more)
jd docker-container
\_ jd0 \_ unix:///var/run/docker.sock running v0.22.0 linux/amd64 (+4), linux/arm64, linux/arm (+2), linux/ppc64le, (7 more)
temp docker-container
\_ temp0 \_ unix:///var/run/docker.sock inactive
default* docker
\_ default \_ default running v0.25.1 linux/amd64 (+4), linux/arm64, linux/arm (+2), linux/ppc64le, (6 more)
teamx docker
\_ teamx \_ teamx running v0.25.1 linux/amd64 (+4), linux/arm64, linux/arm (+2), linux/ppc64le, (6 more)
worker docker
\_ worker \_ worker running v0.24.0 linux/amd64 (+2), linux/arm64, linux/arm (+2), linux/ppc64le, (5 more)
Configuration
Minimal example of my original issue:
variable "FOO" {
type = string
}
target "default" {
args = {
ARG = FOO == null ? "yo" : FOO
}
}Note that ARG = FOO == null actually works... it results in "ARG": "true", so it's being evaluated as null, which suggests the false expression is the one causing the panic:
$ docker buildx bake --print
[+] Building 0.0s (1/1) FINISHED
=> [internal] load local bake definitions 0.0s
=> => reading docker-bake.hcl 107B / 107B 0.0s
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x7fcba1]
goroutine 1 [running]:
github.com/zclconf/go-cty/cty.Type.FriendlyName(...)
github.com/zclconf/go-cty@v1.17.0/cty/type.go:47
github.com/hashicorp/hcl/v2/hclsyntax.describeConditionalTypeMismatch({{0x2f03390?, 0xc0000108e5?}}, {{0x0?, 0x0?}})
github.com/hashicorp/hcl/v2@v2.24.0/hclsyntax/expression.go:1069 +0x401
github.com/hashicorp/hcl/v2/hclsyntax.(*ConditionalExpr).Value(0xc0003aa540, 0xc00000e9a8)
github.com/hashicorp/hcl/v2@v2.24.0/hclsyntax/expression.go:767 +0x68a
github.com/hashicorp/hcl/v2/hclsyntax.(*ObjectConsExpr).Value(0xc0006946e0, 0xc00000e9a8)
github.com/hashicorp/hcl/v2@v2.24.0/hclsyntax/expression.go:1211 +0x27d
github.com/docker/buildx/bake/hclparser/gohcl.DecodeOptions.DecodeExpression({0x2c506c0?, 0x2c51858?}, {0x74931a5151d8, 0xc0006946e0}, 0x2f34b00?, {0xc00053ae00, 0xc00036c088})
github.com/docker/buildx/bake/hclparser/gohcl/decode.go:288 +0x9b
github.com/docker/buildx/bake/hclparser/gohcl.DecodeOptions.decodeBodyToStruct({0x2c506c0?, 0x2c51858?}, {0x2f03278, 0xc0006872e0}, 0xc00000e9a8, {0x2936ec0?, 0xc00036c000?, 0x4166df?})
github.com/docker/buildx/bake/hclparser/gohcl/decode.go:138 +0xd67
github.com/docker/buildx/bake/hclparser/gohcl.DecodeOptions.decodeBodyToValue({0x2c506c0?, 0x2c51858?}, {0x2f03278, 0xc0006872e0}, 0xc00000e9a8, {0x2936ec0?, 0xc00036c000?, 0x50d76d?})
github.com/docker/buildx/bake/hclparser/gohcl/decode.go:57 +0xee
github.com/docker/buildx/bake/hclparser/gohcl.DecodeOptions.DecodeBody({0x2c506c0?, 0x0?}, {0x2f03278, 0xc0006872e0}, 0xc00000e9a8, {0x272d3a0?, 0xc00036c000?})
github.com/docker/buildx/bake/hclparser/gohcl/decode.go:30 +0x11b
github.com/docker/buildx/bake/hclparser.decodeBody(...)
github.com/docker/buildx/bake/hclparser/hclparser.go:1239
github.com/docker/buildx/bake/hclparser.(*parser).resolveBlock(0xc000075400, 0xc00036b6c0, 0x0)
github.com/docker/buildx/bake/hclparser/hclparser.go:525 +0xebd
github.com/docker/buildx/bake/hclparser.Parse({0x2f03240, 0xc00000e6f0}, {0x2c50158?, 0xc000434540?, 0x2c506b8?}, {0x276fa20, 0xc000434570})
github.com/docker/buildx/bake/hclparser/hclparser.go:929 +0x1f1a
github.com/docker/buildx/bake.ParseFiles({0xc000434510, 0x1, 0x1?}, 0xc000434540)
github.com/docker/buildx/bake/bake.go:380 +0xa4f
github.com/docker/buildx/bake.ReadTargets({0xc00022af20?, 0x0?}, {0xc000434510?, 0xc0004075f0?, 0x0?}, {0xc0003a2800, 0x1, 0x0?}, {0x0, 0x0, ...}, ...)
github.com/docker/buildx/bake/bake.go:199 +0x46
github.com/docker/buildx/commands.runBake({_, _}, {_, _}, {_, _, _}, {{0x454d780, 0x0, 0x0}, ...}, ...)
github.com/docker/buildx/commands/bake.go:231 +0x1f3e
github.com/docker/buildx/commands.bakeCmd.func1(0xc000035208, {0xc0003a2430, 0x0, 0x1})
github.com/docker/buildx/commands/bake.go:493 +0x372
github.com/docker/cli/cli-plugins/plugin.RunPlugin.func1.1.2(0xc000035208, {0xc0003a2430, 0x0, 0x1})
github.com/docker/cli@v28.4.0+incompatible/cli-plugins/plugin/plugin.go:65 +0x64
github.com/spf13/cobra.(*Command).execute(0xc000035208, {0xc000406f20, 0x1, 0x1})
github.com/spf13/cobra@v1.10.1/command.go:1015 +0xaaa
github.com/spf13/cobra.(*Command).ExecuteC(0xc0004ad508)
github.com/spf13/cobra@v1.10.1/command.go:1148 +0x46f
github.com/spf13/cobra.(*Command).Execute(...)
github.com/spf13/cobra@v1.10.1/command.go:1071
github.com/docker/cli/cli-plugins/plugin.RunPlugin(0xc0002e8140, 0xc000034c08, {{0x298177a, 0x5}, {0x298be5f, 0xb}, {0x2ec9ad0, 0x7}, {0x0, 0x0}, ...})
github.com/docker/cli@v28.4.0+incompatible/cli-plugins/plugin/plugin.go:80 +0x145
main.runPlugin(0xc0002e8140)
github.com/docker/buildx/cmd/buildx/main.go:64 +0xca
main.run(0xc0002e8140)
github.com/docker/buildx/cmd/buildx/main.go:78 +0xe5
main.main()
github.com/docker/buildx/cmd/buildx/main.go:88 +0x8cSimilarly, this panics as well... null is a legitimate value, and it's reasonable to expect that an undefined variable is equivalent to null in this usage:
variable "FOO" {
type = string
}
target "default" {
args = {
ARG = FOO
}
}$ docker buildx bake --print
[+] Building 0.0s (1/1) FINISHED
=> [internal] load local bake definitions 0.0s
=> => reading docker-bake.hcl 86B / 86B 0.0s
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x7a4d1e]
goroutine 1 [running]:
github.com/zclconf/go-cty/cty.Type.FriendlyName(...)
github.com/zclconf/go-cty@v1.17.0/cty/type.go:47
github.com/zclconf/go-cty/cty/convert.MismatchMessage({{0x0?, 0x0?}}, {{0x2f03390?, 0xc0000108e5?}})
github.com/zclconf/go-cty@v1.17.0/cty/convert/mismatch_msg.go:57 +0x2de
github.com/zclconf/go-cty/cty/convert.mismatchMessageCollectionsFromStructural({{0x2f031d0?, 0xc000069ae0?}}, {{0x2f03198?, 0xc000069b00?}})
github.com/zclconf/go-cty@v1.17.0/cty/convert/mismatch_msg.go:191 +0x38d
github.com/zclconf/go-cty/cty/convert.MismatchMessage({{0x2f031d0?, 0xc000069ae0?}}, {{0x2f03198?, 0xc000069b00?}})
github.com/zclconf/go-cty@v1.17.0/cty/convert/mismatch_msg.go:51 +0x45a
github.com/zclconf/go-cty/cty/convert.Convert({{{0x2f031d0?, 0xc000069ae0?}}, {0x259e020?, 0xc00033d680?}}, {{0x2f03198?, 0xc000069b00?}})
github.com/zclconf/go-cty@v1.17.0/cty/convert/public.go:49 +0x168
github.com/docker/buildx/bake/hclparser/gohcl.DecodeOptions.DecodeExpression({0x2c506c0?, 0x2c51858?}, {0x751c18f50178, 0xc000204640}, 0x2f34b00?, {0xc000310b40, 0xc0003ce088})
github.com/docker/buildx/bake/hclparser/gohcl/decode.go:295 +0x114
github.com/docker/buildx/bake/hclparser/gohcl.DecodeOptions.decodeBodyToStruct({0x2c506c0?, 0x2c51858?}, {0x2f03278, 0xc0000c7ec0}, 0xc000780318, {0x2936ec0?, 0xc0003ce000?, 0x4166df?})
github.com/docker/buildx/bake/hclparser/gohcl/decode.go:138 +0xd67
github.com/docker/buildx/bake/hclparser/gohcl.DecodeOptions.decodeBodyToValue({0x2c506c0?, 0x2c51858?}, {0x2f03278, 0xc0000c7ec0}, 0xc000780318, {0x2936ec0?, 0xc0003ce000?, 0x50d76d?})
github.com/docker/buildx/bake/hclparser/gohcl/decode.go:57 +0xee
github.com/docker/buildx/bake/hclparser/gohcl.DecodeOptions.DecodeBody({0x2c506c0?, 0x0?}, {0x2f03278, 0xc0000c7ec0}, 0xc000780318, {0x272d3a0?, 0xc0003ce000?})
github.com/docker/buildx/bake/hclparser/gohcl/decode.go:30 +0x11b
github.com/docker/buildx/bake/hclparser.decodeBody(...)
github.com/docker/buildx/bake/hclparser/hclparser.go:1239
github.com/docker/buildx/bake/hclparser.(*parser).resolveBlock(0xc000074280, 0xc000357930, 0x0)
github.com/docker/buildx/bake/hclparser/hclparser.go:525 +0xebd
github.com/docker/buildx/bake/hclparser.Parse({0x2f03240, 0xc000780138}, {0x2c50158?, 0xc000261050?, 0x2c506b8?}, {0x276fa20, 0xc000261080})
github.com/docker/buildx/bake/hclparser/hclparser.go:929 +0x1f1a
github.com/docker/buildx/bake.ParseFiles({0xc000260ff0, 0x1, 0x1?}, 0xc000261050)
github.com/docker/buildx/bake/bake.go:380 +0xa4f
github.com/docker/buildx/bake.ReadTargets({0xc0001aaf20?, 0x0?}, {0xc000260ff0?, 0xc000376cc0?, 0x0?}, {0xc000502570, 0x1, 0x0?}, {0x0, 0x0, ...}, ...)
github.com/docker/buildx/bake/bake.go:199 +0x46
github.com/docker/buildx/commands.runBake({_, _}, {_, _}, {_, _, _}, {{0x454d780, 0x0, 0x0}, ...}, ...)
github.com/docker/buildx/commands/bake.go:231 +0x1f3e
github.com/docker/buildx/commands.bakeCmd.func1(0xc0004fd208, {0xc0001fe110, 0x0, 0x1})
github.com/docker/buildx/commands/bake.go:493 +0x372
github.com/docker/cli/cli-plugins/plugin.RunPlugin.func1.1.2(0xc0004fd208, {0xc0001fe110, 0x0, 0x1})
github.com/docker/cli@v28.4.0+incompatible/cli-plugins/plugin/plugin.go:65 +0x64
github.com/spf13/cobra.(*Command).execute(0xc0004fd208, {0xc000376020, 0x1, 0x1})
github.com/spf13/cobra@v1.10.1/command.go:1015 +0xaaa
github.com/spf13/cobra.(*Command).ExecuteC(0xc0004f5508)
github.com/spf13/cobra@v1.10.1/command.go:1148 +0x46f
github.com/spf13/cobra.(*Command).Execute(...)
github.com/spf13/cobra@v1.10.1/command.go:1071
github.com/docker/cli/cli-plugins/plugin.RunPlugin(0xc00042a3c0, 0xc0004fcc08, {{0x298177a, 0x5}, {0x298be5f, 0xb}, {0x2ec9ad0, 0x7}, {0x0, 0x0}, ...})
github.com/docker/cli@v28.4.0+incompatible/cli-plugins/plugin/plugin.go:80 +0x145
main.runPlugin(0xc00042a3c0)
github.com/docker/buildx/cmd/buildx/main.go:64 +0xca
main.run(0xc00042a3c0)
github.com/docker/buildx/cmd/buildx/main.go:78 +0xe5
main.main()
github.com/docker/buildx/cmd/buildx/main.go:88 +0x8cBuild logs
Additional info
There are at least two potential workarounds:
- remove the typing (if it's only used as documentation and not actually relied on)
- add an explicit default;
default = nullavoids the panic in each of those scenarios
I'm assuming the fix will be effectively implementing the second behind the scenes.