Skip to content

[9.2.0] Fix JVM crash from VerifyException in GrpcCacheClient.onNext() (https://github.com/bazelbuild/bazel/pull/29316)#29363

Open
bazel-io wants to merge 1 commit intobazelbuild:release-9.2.0from
bazel-io:cp29316-9.2.0-175508
Open

[9.2.0] Fix JVM crash from VerifyException in GrpcCacheClient.onNext() (https://github.com/bazelbuild/bazel/pull/29316)#29363
bazel-io wants to merge 1 commit intobazelbuild:release-9.2.0from
bazel-io:cp29316-9.2.0-175508

Conversation

@bazel-io
Copy link
Copy Markdown
Member

Description

When a remote cache blob download is cancelled (e.g. dynamic execution choosing the local branch), the output stream is closed via a directExecutor() listener on the download future (CombinedCache#downloadFile). A pending onNext() callback can still be drained afterwards via DelayedClientCall's pending-callback path, which, unlike the normal StreamObserver path, does not convert RuntimeExceptions into onError(). The onNext() handler writes to the closed output stream, then catches the IOException, and throws VerifyException, which escapes to the gRPC executor's worker thread and hits Bazel's default uncaught exception handler.

Replace the throw with graceful error handling: cancel the gRPC stream via the stored requestStream reference and propagate the error through the SettableFuture. In the common case (future already cancelled by dynamic execution), setException is a no-op and the build continues using the local branch.

Motivation

Fixes #22930

Build API Changes

No

Checklist

  • I have added tests for the new use cases (if any).
  • I have updated the documentation (if applicable).

Release Notes

RELNOTES: None

Closes #29316.

PiperOrigin-RevId: 901186846
Change-Id: Id9d9ca1bd824c0d4c62d69f05b6c9dbf606ab3ec

Commit 588172a

…build#29316)

### Description
When a remote cache blob download is cancelled (e.g. dynamic execution choosing the local branch), the output stream is closed via a directExecutor() listener on the download future (CombinedCache#downloadFile). A pending onNext() callback can still be drained afterwards via DelayedClientCall's pending-callback path, which, unlike the normal StreamObserver path, does not convert RuntimeExceptions into onError(). The onNext() handler writes to the closed output stream, then catches the IOException, and throws VerifyException, which escapes to the gRPC executor's worker thread and hits Bazel's default uncaught exception handler.

Replace the throw with graceful error handling: cancel the gRPC stream via the stored requestStream reference and propagate the error through the SettableFuture. In the common case (future already cancelled by dynamic execution), setException is a no-op and the build continues using the local branch.

### Motivation
Fixes bazelbuild#22930

### Build API Changes

No

### Checklist

- [ ] I have added tests for the new use cases (if any).
- [ ] I have updated the documentation (if applicable).

### Release Notes

RELNOTES: None

Closes bazelbuild#29316.

PiperOrigin-RevId: 901186846
Change-Id: Id9d9ca1bd824c0d4c62d69f05b6c9dbf606ab3ec
@bazel-io bazel-io requested a review from a team as a code owner April 21, 2026 17:55
@bazel-io bazel-io added team-Remote-Exec Issues and PRs for the Execution (Remote) team awaiting-review PR is awaiting review from an assigned reviewer labels Apr 21, 2026
@bazel-io bazel-io requested review from coeuvre and fmeum April 21, 2026 17:55
@iancha1992 iancha1992 requested review from tjgq and removed request for fmeum April 21, 2026 17:58
@iancha1992 iancha1992 enabled auto-merge (squash) April 21, 2026 17:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting-review PR is awaiting review from an assigned reviewer team-Remote-Exec Issues and PRs for the Execution (Remote) team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant