Skip to content

fix(bes): stream a feature-injected BES backend from every task - #1455

Open
joshcbarnes wants to merge 1 commit into
mainfrom
fix-bes-backend-forwarding
Open

joshcbarnes wants to merge 1 commit into
mainfrom
fix-bes-backend-forwarding

Conversation

@joshcbarnes

Copy link
Copy Markdown
Contributor

--remote=bes reached build and test, and silently streamed nowhere for format, gazelle, lint, run, warming, and delivery.

The bug

The Deployment feature puts its backend on BazelTrait.bes_backends, but collect_bes_sinks took those URIs as an extra_backends parameter rather than reading the trait it is already handed. Only bazel/invocation.axl — the spawn path behind build/test — passed them:

extra_backends = list(trait.bes_backends)
sinks = collect_bes_sinks(ctx, trait, rc, command, extra_backends = extra_backends)

The six tasks that build their own sinks call it with no extra_backends, so the default [] dropped the feature's backend on the floor. No error and no disclosure — those builds simply reported to nothing.

The cache half never had the problem, which is what made it confusing to diagnose: --remote=cache lands in BazelTrait.base_flags, which the spawn path reads generically, so it reaches every task. Only the BES half needed each caller to cooperate.

Observed on a GitHub-hosted CI job: format got --remote_cache=grpcs://cache.aspect.build and the credential helper, but no BES stream — so the invocation never appeared in the Web UI, while build and test from the same run did.

History

This completes what #1374 set out to do. It introduced the seam and stated the goal:

--remote and --deployment … now reach every bazel-driving task rather than just build/test.

It added BazelTrait.bes_backends without a consumer. #1326, a day later, wired it up — in invocation.axl only, touching build.axl, test.axl, trait.axl and bazel.axl. The six tasks with their own sink construction were never revisited.

The fix

collect_bes_sinks and dropped_bes_backends read bazel_trait.bes_backends themselves, so a feature-injected backend reaches a task by construction rather than by each call site remembering. That's deliberately the opposite of threading the parameter through six more call sites: a parameter that must be passed identically everywhere is what produced the bug.

extra_backends stays for a caller with a backend of its own, unioned with the trait's and deduped, so a caller that still passes them gets one sink rather than two. The now-redundant threading in invocation.axl is dropped.

Endpoint precedence is unchanged: a backend Bazel uploads to itself via --bes_backend is still dropped from the CLI's sinks and still named in the "Not streaming …" disclosure.

Test plan

  • New _test_feature_injected_backend_reaches_every_task in build_events_test.axl: a backend on the trait is streamed with no extra_backends from the caller; it is still dropped when Bazel uploads there itself and still named by dropped_bes_backends; a caller passing the same backend is deduped. _fake_trait grows a bes_backends field.
  • Confirmed the test fails with the fix revertedfail: streamed with no extra_backends from the caller — rather than passing either way.
  • End-to-end against a build from this branch, simulating a GitHub-hosted runner with --remote=cache,bes: aspect format streams to grpcs://bes.aspect.build 0 times before the fix and 1 time after.
  • aspect dev test-bes-sinks (19), test-bazel-invocation (11 sections), test-deployment-flags (19), test-bazel-flags all pass; aspect format clean.

Notes for reviewers

Changes are visible to end-users: yes

  • aspect <task> --remote now streams build events from every Bazel-driving task. format, gazelle, lint, run, warming, and delivery previously wired the remote cache but silently streamed no build events, so their invocations never reached the Aspect Web UI.

🤖 Generated with Claude Code

`--remote=bes` reached `build` and `test` and silently streamed nowhere
for `format`, `gazelle`, `lint`, `run`, `warming`, and `delivery`.

The `Deployment` feature puts its backend on `BazelTrait.bes_backends`,
but `collect_bes_sinks` took those URIs as an `extra_backends` parameter
rather than reading the trait it is already handed. Only
`bazel/invocation.axl` — the spawn path behind `build`/`test` — passed
them. The six tasks that build their own sinks call it with no
`extra_backends`, so the default `[]` dropped the feature's backend on
the floor. No error, no disclosure: those builds simply reported to
nothing.

The cache half never had the problem, which is what made it confusing:
`--remote=cache` lands in `BazelTrait.base_flags`, read generically by
the spawn path, so it reaches every task. Only the BES half needed each
caller to cooperate.

This completes what #1374 set out to do — it introduced the seam and
said `--remote` "now reach[es] every bazel-driving task rather than just
build/test" — and what #1326 wired a day later in `invocation.axl`
alone.

`collect_bes_sinks` and `dropped_bes_backends` now read
`bazel_trait.bes_backends` themselves, so a feature-injected backend
reaches a task by construction rather than by each call site
remembering. `extra_backends` stays for a caller with a backend of its
own and is unioned with the trait's, so a caller that still passes them
(as `invocation.axl` did) gets one sink, not two; that now-redundant
threading is dropped.

Endpoint precedence is unchanged: a backend Bazel uploads to itself via
`--bes_backend` is still dropped from the CLI's sinks and still named in
the "Not streaming …" disclosure.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Sep 15, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 37a55acf-38ef-4da2-a05d-8598c1372588

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@aspect-workflows

aspect-workflows Bot commented Sep 15, 2026

Copy link
Copy Markdown

Aspect Workflows Tasks

📅 Tue Sep 15 23:15:15 UTC 2026

Task Results

Reproduce

❌ delivery (delivery-uncacheable · delivery-gha-debug · delivery-gha · delivery-uncacheable-warn)

# --mode=always --track-state=false for off-runner with no state backend.
aspect delivery \
  --commit-sha=5aebc84efa42bcbc7f572396595ff25619726c8b \
  --mode=always \
  --track-state=false \
  --dry-run=true

Install aspect: aspect.build/docs/cli/install


⏱ Last updated Tue Sep 15 23:21:09 UTC 2026 · 📊 GitHub API quota 259/7,700 (3% used, resets in 55m)
🚀 Powered by Aspect CLI (v0.0.0-dev)  |  Aspect Build · X · LinkedIn · YouTube

@joshcbarnes
joshcbarnes requested a review from jbedard September 15, 2026 23:15

@jbedard jbedard left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

silently streamed nowhere for format, gazelle, lint, run, warming, and delivery.

Can those be tested somehow?

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants