4.10.7 Extension Repository Manipulation
extrainject_repo() and override_repo() are root-module escape hatches for a module extension's repository namespace. They do not change which Bazel modules participate in version resolution. They change which already-visible repository an extension-generated repository name points to, or which additional repository an extension can see while it runs.1 Reach for them when the problem is inside an extension's repo set, after the normal Bzlmod tools from 3.1.1 Bzlmod (MODULE.bazel) are too coarse.
The Scope They Modify
A module extension creates repositories in its own namespace. Repositories generated by the same extension can see each other by the names used in the repository rule calls. A module sees extension-generated repositories only after importing them with use_repo(), alongside other repositories introduced directly in its MODULE.bazel file.2 That namespace boundary is why these APIs exist: the root module sometimes has a repository that an extension should use, but the extension would otherwise generate a different one or not see it at all.
Both functions take the extension proxy returned by use_extension(). They are root-module-only controls. If the current module is not the root module, or if --ignore_dev_dependency is enabled, the API reference says they are ignored.3
toolchains = use_extension("@rules_java//java:extension.bzl", "toolchains")
override_repo(toolchains, remote_java_tools = "my_java_tools")
In that shape, the key is the repository name in the extension's namespace, and the value is a repository visible to the current module. The positional form is shorthand for same-name replacement or injection. The keyword form lets the root module map different names.3
Override When the Extension Already Creates the Repo
Use override_repo() when the extension already defines a repository and the root module wants a different implementation for that name.3 The official module-extension guide shows this with rules_java: the root module first creates a local repository named my_java_tools, then overrides the extension's remote_java_tools repository with that vendored copy.4
This is narrower than local_path_override() or single_version_override(). A module override replaces a Bazel module before extension evaluation. override_repo() replaces one repository produced by one extension usage. That makes it a good debugging or vendoring tool when the ruleset's extension is mostly right, but one generated repository needs to point somewhere else.
Inject When the Extension Needs One More Repo
Use inject_repo() when the extension does not already create the repository, but its generated repositories need that repository in their visible scope.3 The official guide's Gazelle example patches a Go dependency to depend on @zlib, then injects the root module's zlib repository into the go_deps extension scope so the patched generated BUILD file can resolve that label.5
That distinction matters in migrations. override_repo() is the no-patch choice when replacing a same-named repository, and inject_repo() is the choice when a patch introduces a new repository reference that the dependency's extension must be able to see.6 In both cases, the point is to reuse an existing module extension instead of forking it or writing a custom extension just to expose one vendored dependency.
Name the Boundary Deliberately
These APIs are about apparent repository names, not canonical repository strings. Bazel's documentation says extension-generated repositories have canonical names derived from module and extension identity, but that canonical format is not an API.2 Treat the extension's documented generated repo names as the contract, and keep the naming rules from 4.10.5 Repo Name Handling in mind when passing labels across module and extension boundaries.
If a repository name is not a valid Starlark identifier, pass a literal dict through **kwargs, for example:
override_repo(extension_proxy, **{"foo.2": "local_foo"})
inject_repo(extension_proxy, **{"foo.2": "local_foo"})
The API reference documents this form for both functions.3 It is rare, but it prevents the workaround from changing the repo name just to fit Starlark keyword syntax.
When Not to Use It
Do not use extension repository manipulation as a general dependency-policy layer. If the thing you need to replace is a Bazel module from a registry, use the ordinary root-module overrides from 3.1.1 Bzlmod (MODULE.bazel). If the extension author should expose a stable configuration tag, fix the extension API instead of forcing every root module to patch around it. If the repository is a toolchain or SDK implementation, this can be a useful local escape hatch, but the long-term published shape belongs with the toolchainization and setup surface in 4.11.2 Toolchainization.
Use override_repo() to replace a repository an extension already generates. Use inject_repo() to make one more root-visible repository available inside the extension's namespace. Both are root-module controls for surgical debugging, vendoring, and migration cases, not substitutes for a well-designed extension API.
Check your understanding · 3 questions
1.When should the root module use override_repo() instead of inject_repo()?
Select one answer
2.True or false: extension repository manipulation.
Choose True or False for each sentence
inject_repo() and override_repo() are root-module controls.override_repo() replaces a Bazel module before version resolution.inject_repo() can make a root-visible repository available inside an extension's namespace.inject_repo() and override_repo() operate on apparent repository names inside one extension namespace, not on canonical repository-name strings.3.Match the mechanism to the situation it best fits.
Drag each answer onto the matching prompt, or click an answer and then click a prompt
local_path_override()override_repo()inject_repo()Footnotes
-
Module extensions — "Overriding and injecting module extension repos" introduces
override_repo()andinject_repo()as root-module controls for extension repositories. ↩ -
Module extensions — repository names and visibility rules for repos generated by module extensions. ↩1 ↩2
-
MODULE.bazel files — API reference for
inject_repo()andoverride_repo(), including root-module-only behavior and args/kwargs mapping. ↩1 ↩2 ↩3 ↩4 ↩5 -
Module extensions —
rules_javaexample replacingremote_java_toolswith a vendoredmy_java_toolsrepository. ↩ -
Module extensions — Gazelle example patching a Go dependency to depend on
@zliband injecting thezlibrepo. ↩ -
Migrating to Bazel Modules (a.k.a. Bzlmod) - Fixing and Patching Breakages — practical guidance on choosing
override_repo()vsinject_repo()for vendored repositories during migration. ↩