Skip to content

Patching MODULE.bazel has no effect on module extension evaluation #28560

@philwo

Description

@philwo

Description of the bug:

@meteorcloudy @Wyverald I noticed this today while trying to upgrade remote-apis and remote-apis-sdks to Bazel 9.0.0 and the latest gRPC / protobuf dependencies. 😊 I think I can find a workaround for my particular case, but it would be really nice if this approach worked. Maybe I'm also doing something wrong, not sure - I included a minimum repro example below!

Bazel apparently doesn't apply patches from a single_version_override prior to evaluating the MODULE.bazel file downloaded from BCR. I believe that this should work, as it's also documented: "If a patch makes changes to the MODULE.bazel file, these changes will only be effective if the patch file is provided by the root module." (https://bazel.build/rules/lib/globals/module#parameters_12)

This means that if there's a bug affecting a BCR module, like currently in gRPC 1.78.0 where the MODULE.bazel passes an invalid Python version to python.toolchain (grpc/grpc#41438), I cannot patch that out locally like this:

$ touch BUILD.bazel
$ cat > MODULE.bazel <<'EOF'
module(
    name = "cant_patch_this",
    version = "",
)

bazel_dep(name = "grpc", version = "1.78.0")

# grpc pulls in a version of rules_foreign_cc that is incompatible with Bazel 9.0.0, so let's
# override it to a newer one.
single_version_override(
    module_name = "rules_foreign_cc",
    version = "0.15.1",
)

# grpc 1.78.0 has a bug in its MODULE.bazel file, where it passes the invalid Python version
# "3.14.0b2" to rules_python's python.toolchain module extension. This causes it to crash with
# the error "Error: key "3.14.0b2" not found in dictionary".
#
# Let's just patch that invalid Python version out of the MODULE.bazel file.
single_version_override(
    module_name = "grpc",
    patches = [
        "//:grpc_1_78_0_remove_invalid_python_version.patch",
    ],
)
EOF

$ cat > grpc_1_78_0_remove_invalid_python_version.patch <<'EOF'
diff --git a/MODULE.bazel b/MODULE.bazel
index 2a1c5aec1e..a2573a25c6 100644
--- a/MODULE.bazel
+++ b/MODULE.bazel
@@ -68,7 +68,6 @@ PYTHON_VERSIONS = [
     "3.11",
     "3.12",
     "3.13",
-    "3.14.0b2",
 ]

 python = use_extension("@rules_python//python/extensions:python.bzl", "python")
EOF

The patch has no effect, and Bazel still prints the error about the invalid Python version:

$ bazel mod show_repo grpc
Starting local Bazel server (9.0.0) and connecting to it...
ERROR: /home/philwo/.cache/bazel/_bazel_philwo/352ff19a566314e79a838237cef373aa/external/rules_python+/python/private/python_register_toolchains.bzl:106:31: Traceback (most recent call last):
        File "/home/philwo/.cache/bazel/_bazel_philwo/352ff19a566314e79a838237cef373aa/external/rules_python+/python/private/python.bzl", line 281, column 53, in _python_impl
                register_result = python_register_toolchains(
        File "/home/philwo/.cache/bazel/_bazel_philwo/352ff19a566314e79a838237cef373aa/external/rules_python+/python/private/python_register_toolchains.bzl", line 106, column 31, in python_register_toolchains
                sha256 = tool_versions[python_version]["sha256"].get(platform, None)
Error: key "3.14.0b2" not found in dictionary
ERROR: error evaluating module extension @@rules_python+//python/extensions:python.bzl%python
## grpc@1.78.0:
load("@@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
  name = "grpc+",
  urls = ["https://github.com/grpc/grpc/archive/refs/tags/v1.78.0.tar.gz"],
  integrity = "sha256-4qznkKXy0PgyWdE5CoFqM7AT6jTfLoYITZJ+WNqkxdk=",
  strip_prefix = "grpc-1.78.0",
  remote_patches = {"https://bcr.bazel.build/modules/grpc/1.78.0/patches/adopt_bzlmod.patch": "sha256-d7z79/WSEiNTZiQ/A50HMbyqbZj3qIESa4H2n/yhlhA=", "https://bcr.bazel.build/modules/grpc/1.78.0/patches/fix_googleapis_switched_rules.patch": "sha256-WTFS3rp23Cj/jlOWbLnu01AtTiun02+3MTXVAzDxpeA="},
  remote_file_urls = {},
  remote_file_integrity = {},
  remote_module_file_urls = ["https://bcr.bazel.build/modules/grpc/1.78.0/MODULE.bazel"],
  remote_module_file_integrity = "sha256-anLwsv6VA0L+Y7Ixx2GX320Reo6hrDONrECwUwIPWGo=",
  remote_patch_strip = 1,
  patches = [Label("//:grpc_1_78_0_remove_invalid_python_version.patch")],
  patch_cmds = [],
  patch_args = ["-p0"],
)

ERROR: Results may be incomplete as 2 extensions failed.
    Fetching module extension @@rules_python+//python/extensions:python.bzl%python; starting

By the way, it was very difficult to understand where this mysterious "3.14.0b2" string comes from, because Bazel doesn't save anything to disk when this evaluation fails, which means that there's absolutely nothing to be found in my output_base. The only place where you can find something is in the CAS of the repo cache.

$ fgrep -r "3.14.0b2" "$(bazel info output_base)"
<nothing>

$ fgrep -r "3.14.0b2" ~/.cache/bazel
/home/philwo/.cache/bazel/_bazel_philwo/cache/repos/v1/content_addressable/sha256/6a72f0b2fe950342fe63b231c76197df6d117a8ea1ac338dac40b053020f586a/file:    "3.14.0b2",

In the end, I used a debugger and set a breakpoint in the Starlark interpreter to find out where it comes from, where it was clearly visible. It would probably be nice to print this location in the error message.

Image

Which category does this issue belong to?

No response

What's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.

See above.

Which operating system are you running Bazel on?

I use Arch, btw

What is the output of bazel info release?

release 9.0.0 (reproducible with latest main branch, too)

If bazel info release returns development version or (@non-git), tell us how you built Bazel.

No response

What's the output of git remote get-url origin; git rev-parse HEAD ?

git@github.com:philwo/herb.git
32eef3485d66f448df4b66fe4f0d530e1a88f99b

If this is a regression, please try to identify the Bazel commit where the bug was introduced with bazelisk --bisect.

No response

Have you found anything relevant by searching the web?

https://stackoverflow.com/questions/79018238/single-version-override-with-patch-has-no-effect

Any other information, logs, or outputs that you want to share?

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1I'll work on this now. (Assignee required)team-ExternalDepsExternal dependency handling, remote repositiories, WORKSPACE file.type: bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions