Bazelrc
The Bazelrc language surface implements upstream Bazel 8.7.0. It is separate
from Starlark: Bazelrc files are never parsed, formatted or linted by
buildifier.
Behavior inventory
Reviewed
against upstream Bazel 8.7.0. Each entry
states the language server's exact behavior and boundary.
Version and files
| Capability | Exact behavior |
|---|---|
| Upstream Bazelrc language | Pinned to upstream Bazel 8.7.0. |
| Native flag catalog | Only a configured executable reporting numeric major 8 and minor 7. |
| Structural editing with another Bazel version | The 8.7 parser remains active; compatibility with another release is not claimed. |
| Nearest-version or bundled catalog fallback | No catalog loads unless the executable reports numeric 8.7; no nearest or bundled fallback is used. |
| Vendor-only grammar and configuration semantics | A vendor-suffixed numeric 8.7 executable supplies its flags; grammar and configuration semantics remain upstream 8.7. |
| .bazelrc and *.bazelrc classification | The filename must be exact or end in .bazelrc. |
| Arbitrary imported filenames | A regular file becomes Bazelrc when reached from the workspace import graph. |
| Unrelated open files such as bazel.rc | Not classified as Bazelrc without a .bazelrc suffix or published import-graph membership. |
| Starlark parsing, buildifier formatting, or lint | Bazelrc remains an independent native-client language and is never sent to buildifier. |
Logical grammar
| Capability | Exact behavior |
|---|---|
| LF and CRLF continuation deletion | Deleted globally before line splitting, including in quotes and comments. |
| Native whitespace delimiters | Space, TAB, CR, and LF delimit; logical-line edges also strip vertical TAB and form feed. |
| Mid-token comments | An unescaped, unquoted # ends the logical line. |
| Single/double quotes and fragment concatenation | Quote bytes are removed; adjacent fragments form one token. |
| Backslash byte escaping | Inside and outside quotes; no shell expansion is performed. |
| Unclosed quotes and dangling backslashes | Accepted as Bazel's native tokenizer accepts them. |
| Empty quoted tokens | Discarded rather than retained as empty arguments. |
| Physical ranges across continuations | Editor ranges map logical tokens back to the original UTF-8 bytes. |
| Argless ordinary entries | Bazel 8.7 discards them; they declare no empty configuration. |
Imports and discovery
| Capability | Exact behavior |
|---|---|
| import PATH | Exact arity; read failures are errors. |
| try-import PATH | Exact arity; read failures are quiet. |
| try-import-if-bazel-version CONDITION PATH | Bazel 8.7 SemVer grammar, evaluated against baseline 8.7.0. |
| Configured vendor label in conditional imports | Conditions do not use suffixes such as 8.7.0-imc2. |
| Depth-first textual import expansion | No later-version import-depth cap. |
| Diamond import replay | Entries replay and the repeated import receives a warning. |
| Active import cycle detection | Reported as an error. |
| Exact %workspace%/ substitution | Other %workspace% spellings are literal paths. |
| Absolute and workspace-root-relative paths | The server models the Bazel client working directory as the workspace root. |
| Per-invocation subdirectory working directory | Relative imports resolve from the workspace root; Bazel launched below it may resolve the same spelling differently. |
| Live refresh for imports outside the workspace | They load into snapshots, but external edits require manual reindexing. |
| Containing-file-relative imports | Relative imports resolve from the workspace root, never from the containing file. |
| Environment-variable or tilde expansion | $VAR, ${VAR}, and ~ remain literal. |
| Workspace .bazelrc graph | The sole graph root; all reachable imports are indexed. |
| System, home, and explicit --bazelrc layers | Not reconstructed by the language server. |
| Bazel 9.0 BAZELRC environment list | Not read because it is outside the 8.7 contract. |
| New unsaved import targets | Open graph members may reuse published targets; a new target loads after save and refresh. |
Commands and configs
| Capability | Exact behavior |
|---|---|
| Bazel 8.7 commands and rc scopes | Static exact list, including always, common, and startup. |
| Command inheritance | Build/test/coverage and other 8.7 inheritance is transitive. |
| Unknown command sections | Warned; excluded from config indexing and flag completion/checks. Native hover may still identify a spelling. |
| Named configuration declarations | Recognized, non-startup base plus at least one option. |
| startup:name configurations | Not indexed as named configurations because startup parsing cannot consume command --config. |
| Top-level --config=name and --config name | Both spellings create configuration references. |
| Nested --config=name | Included in completion, navigation, and absence diagnostics. |
| Bazel's recursive --config prefix quirk | Named bodies expand any token beginning --config through its first =, before native parsing. |
| Nested split --config name | Bazel 8.7 rejects it; the server reports an error. |
| Applicable configuration completion | Follows command inheritance and all declarations in the graph. |
| Open-buffer declaration overlays | An open file replaces declarations from its saved path. |
| Configuration go-to-definition | Returns every applicable saved or open declaration. |
| Effective option/config expansion | Graph analysis is supported; a final option sequence is not rendered. |
| Configuration expansion-cycle diagnostics | Branch-local active-chain cycles are errors. |
| Repeated/deep expansion warnings | Every occurrence is traversed; chains of ten or more configurations warn. |
| Automatic platform configuration selection | Does not evaluate --enable_platform_specific_config. |
Native flags
| Capability | Exact behavior |
|---|---|
| help flags-as-proto acquisition | Runs in the Bazel actor with all rc files ignored. |
| Bazel 8.7 proto fields 1–16 | All reported documentation and semantic metadata are decoded. |
| Canonical long flag completion | Filtered to the current command and visible catalog entries. |
| Negative and one-character abbreviation completion | Includes Bazel's negative -x- spelling. |
| Old-name completion | Old names resolve for hover/diagnostics but are not suggested. |
| common flag union | Known in any reported non-startup command. |
| always safe flag intersection | Known in every reported non-startup command. |
| Native flag hover | Docs, spellings, type, default, enums, scopes, tags, and expansions. |
| Required-value and negative-boolean checks | Only contradictions proven by the exact catalog are errors. |
| Scope, old-name, deprecation, and status checks | Severity follows the strength of catalog evidence. |
| Starlark build-setting flag exemption | --//, --@, --no//, and --no@ bypass native lookup. |
| Internal flags omitted by Bazel | flags-as-proto does not expose INTERNAL options. |
| Flag aliases and external rc aliases | Not resolved because they are outside the native catalog and workspace snapshot. |
| Enum value completion | Only exact nonempty enum sets reported by the 8.7 catalog. |
| Enum membership validation | ASCII-case-insensitive, matching Bazel's converter, and only for an exact reported enum set. |
| Other flag-value completion | Returns no values because non-enum converters do not expose a finite set. |
| Converter-specific value validation | The server does not execute Bazel option converters. |
Language server
| Capability | Exact behavior |
|---|---|
| Command and directive completion | Available without Bazel. |
| Import-path completion | At most 512 eligible matches from a 131,072-path snapshot; ignored, metadata, output, symlink, non-regular, and non-UTF-8 paths are excluded. |
| Import document links | Only active imports whose targets loaded successfully. |
| Import go-to-definition | Only active imports whose targets loaded successfully. |
| Semantic tokens | Directives/keys, conditions, paths, option tokens, and comments. |
| Separate flag-value semantic tokens | A value token uses the same property category as its option. |
| Continuation and comment-run folding | Catalog-independent structural ranges. |
| Token, logical-line, and file selection ranges | Catalog-independent structural ranges. |
| Current-buffer syntax diagnostics | Published on each document change. |
| Saved import-graph diagnostics | Shown only while the open text still matches the indexed file. |
| Missing configuration warnings | Qualified to the published workspace graph; never called invalid. |
| Command/config/import hover | Structural facts are available without a flag catalog. |
| Document and workspace symbols for configurations | Declarations use decoded names and exact name-only ranges. |
| Configuration references and highlights | Case-sensitive decoded identity across saved and open graph files. |
| Rename | Declared names only; nonempty bare fragments; collisions are refused. |
| Formatting | Returns no edits because Bazel defines no canonical semantics-safe layout. |
| Implementation, code lens, and inlay hints | Bazelrc handlers return no results. |
The tracked Bazelrc 8.7 specification defines the implementation contract behind this inventory.
Files and imports
The server recognizes .bazelrc, every *.bazelrc file, and arbitrary
filenames reached from the workspace import graph. It indexes the workspace
.bazelrc, expanding reachable imports depth-first at their textual position.
Supported directives are import, try-import, and the Bazel 8.7
try-import-if-bazel-version. Required imports report read failures; missing
optional imports do not. %workspace%/ is recognized exactly. Other relative
paths resolve from the workspace root: the server models one Bazel invocation
working directory, while a command launched from a workspace subdirectory may
resolve the same spelling differently. Imports are never containing-file
relative.
Import paths receive workspace-file completion, document links, structural hover, and go-to-definition. Completion returns at most 512 eligible matches from the bounded workspace snapshot and quotes paths whose bytes would otherwise be tokenized differently. Imports outside the workspace load, but changes to those external files require a manual reindex.
Commands and configurations
Completion covers the Bazel 8.7 commands and the startup, common, and
always rc scopes. Configuration completion and go-to-definition follow all
applicable declarations in the workspace import graph, with open buffers taking
precedence over saved files.
Nested configurations use --config=name. Bazel rejects split --config name
inside a named configuration body, and the server reports it as an error. The
server also models Bazel 8.7’s source-level quirk that any nested token whose
first eight bytes are --config is expanded through its first = before
native option parsing.
Configuration names absent from the published workspace graph are warnings,
not invalid-name errors, because another rc layer may declare them.
The server reports branch-local expansion cycles, repeated configuration expansion, and chains of ten or more configurations. It does not render a final effective option sequence or automatically select a platform configuration.
Native flags
When the configured executable reports numeric release 8.7, the server reads
that binary’s help flags-as-proto output with rc files disabled. The resulting
catalog supplies:
- command-filtered canonical, negative and abbreviated completion;
- exact enum-value completion and membership checks;
- hover with documentation, type, default, enum values, alternate spellings, commands, expansion, effect and metadata facts;
- diagnostics for exact scope contradictions, missing required values, negative booleans with values, old names, deprecation, and no-op or hidden status.
common completion is the union of flags known to any non-startup command.
always completion is the safe intersection across the binary’s reported
non-startup commands.
A native-looking spelling absent from the catalog is reported only as “not recognized by the Bazel 8.7 native flag catalog.” The catalog omits internal flags, and Starlark settings, aliases, vendor behavior or external rc layers may still explain a spelling. Recognizable Starlark setting forms are exempt from native lookup.
Structural features
Semantic highlighting distinguishes directives and command keys, version conditions, import paths, option tokens and comments. Continued lines and comment runs fold, and selection ranges expand through tokens and logical lines. Commands, rc scopes, imports, and configurations have structural hover. Configuration names support references, document highlights, document and workspace symbols, and conservative workspace rename. These features do not require Bazel.
Formatting
Formatting intentionally returns no edits. Bazel 8.7 defines tokenization but no canonical rc-file layout, and whitespace changes around continuations, comments, quotes, and escapes can change the option stream. Bazelrc files are never sent to buildifier.
Boundaries
The inventory above is the exhaustive public record as of its review date.