Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pkg/buildx/commands/bake.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func RunBake(dockerCli command.Cli, in BakeOptions, validator BakeValidator, pri

ctx, end, err := tracing.TraceCurrentCommand(ctx, "bake")
if err != nil {
return nil, nil, err
return nil, nil, wrapBuildError(err, true)
}
defer func() {
end(err)
Expand Down
12 changes: 11 additions & 1 deletion pkg/buildx/commands/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ func runBuild(dockerCli command.Cli, validatedOpts map[string]build.Options, in

ctx, end, err := tracing.TraceCurrentCommand(ctx, "build")
if err != nil {
return err
return wrapBuildError(err, false)
}
defer func() {
end(err)
Expand Down Expand Up @@ -1086,6 +1086,16 @@ func wrapBuildError(err error, bake bool) error {
if err == nil {
return nil
}

errMsg := err.Error()

// Check for OpenTelemetry schema conflict errors
if strings.Contains(errMsg, "conflicting Schema URL") || strings.Contains(errMsg, "cannot merge resource") {
msg := fmt.Sprintf("%s\n\nThis error is usually caused by conflicting OpenTelemetry environment variables.\nTo resolve this issue, try setting DEPOT_DISABLE_OTEL=1 in your environment.", errMsg)
return &wrapped{err, msg}
}

// Check for gRPC errors
st, ok := grpcerrors.AsGRPCStatus(err)
if ok {
if st.Code() == codes.Unimplemented && strings.Contains(st.Message(), "unsupported frontend capability moby.buildkit.frontend.contexts") {
Expand Down
79 changes: 79 additions & 0 deletions pkg/buildx/commands/build_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package commands

import (
"errors"
"strings"
"testing"
)

func TestWrapBuildError_SchemaConflict(t *testing.T) {
tests := []struct {
name string
err error
bake bool
shouldWrap bool
expectedInMsg string
}{
{
name: "nil error",
err: nil,
bake: false,
shouldWrap: false,
},
{
name: "conflicting Schema URL error",
err: errors.New("Error: cannot merge resource due to conflicting Schema URL"),
bake: false,
shouldWrap: true,
expectedInMsg: "DEPOT_DISABLE_OTEL=1",
},
{
name: "cannot merge resource error",
err: errors.New("cannot merge resource with different schema"),
bake: true,
shouldWrap: true,
expectedInMsg: "OpenTelemetry environment variables",
},
{
name: "unrelated error",
err: errors.New("some other error"),
bake: false,
shouldWrap: false,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := wrapBuildError(tt.err, tt.bake)

if tt.err == nil {
if result != nil {
t.Errorf("expected nil error, got %v", result)
}
return
}

if tt.shouldWrap {
wrapped, ok := result.(*wrapped)
if !ok {
t.Errorf("expected wrapped error, got %T", result)
return
}

if !strings.Contains(wrapped.Error(), tt.expectedInMsg) {
t.Errorf("expected error message to contain %q, got %q", tt.expectedInMsg, wrapped.Error())
}

// Verify we can unwrap to get the original error
if errors.Unwrap(result) != tt.err {
t.Errorf("expected unwrapped error to be original error")
}
} else {
// Should return the original error unchanged
if result != tt.err {
t.Errorf("expected error to be unchanged, got %v", result)
}
}
})
}
}
Loading