| name | buildbuddy_api |
| description | Reference for querying the BuildBuddy API: build/test logs, invocations, RBE execution details, cache stats, undeclared test outputs, target pass/fail history for bisecting, workflow re-runs. Use for any why-did-CI-fail, show-me-the-log, or when-did-this-test-break task. |
BuildBuddy API
Prerequisites
All commands require BUILDBUDDY_API_KEY to be set (session hook exports it automatically).
Official bb CLI
The official BuildBuddy CLI (bb) handles build logs and execution details:
bb view <invocation-id-or-url> [--lines=100000]
bb execution get <execution-id> [--output=json]
bb download <digest>/<size> [--type=Action|Command]
bbapi CLI
bbapi provides API query features not available in bb:
bbapi invocation <invocation-id>
bbapi invocation list [--repo URL] [--count N]
bbapi target log <invocation-id> <target-label-or-substring>
bbapi target <invocation-id> [--filter SUBSTR] [--label LABEL]
bbapi target history [--repo URL] [--label LABEL] [--failures-only]
bbapi target stats [--repo URL]
bbapi target flakes <target-label> [--repo URL]
bbapi artifact list <invocation-id>
bbapi artifact list <invocation-id> --kind build
bbapi artifact cat <invocation-id> <name-substring>
bbapi artifact download <invocation-id> <name-substring> [-o PATH]
bbapi tool-log list <invocation-id>
bbapi tool-log cat <invocation-id> "critical path"
bbapi tool-log download <invocation-id> command.profile.gz [-o PATH]
bbapi tool-log download <runner-invocation-id> command.profile.gz --all -o profiles/
bbapi execution <invocation-id>
bbapi execution search <query>
bbapi execution files <invocation-id> <execution-id>
bbapi invocation stat [--agg-type branch|user|host|repo|commit|pattern] [--repo URL] [--limit N]
bbapi ask <invocation-id> [--prompt TEXT]
bbapi workflow
bbapi workflow run [--workflow-id ID] [--branch BRANCH] [--commit SHA] [--action NAME] [--async]
bbapi cache <invocation-id>
bbapi cache metadata <digest> <size-bytes>
bbapi trend [--days N] [--repo URL]
All bbapi commands support --json for raw JSON output.
Responses are parsed against pinned BuildBuddy protos but unknown fields are
discarded, so bbapi tolerates API/proto drift between repins (newly added
response fields) instead of hard-failing on the parse.
Investigating Failed CI Builds
Typical workflow for debugging a failed CI build:
bbapi invocation <invocation-id>
bb view <invocation-id>
bbapi target log <invocation-id> <target-substring>
Workflow vs Child Invocations
BuildBuddy CI runs use workflow invocations that spawn child invocations.
The workflow invocation (command: workflow run) is a wrapper; the child
invocation contains the actual bazel test results, targets, and artifacts.
bbapi invocation shows Child: <child-id> for workflow invocations
bbapi artifact {list,cat,download} and bbapi target log auto-resolve
workflow invocations to their children — you can pass either the workflow
or child ID
bbapi target also auto-resolves workflow invocations to their children
Artifact Name Matching
bbapi artifact {cat,download} and bbapi target log match against "label/name":
"test_lifecycle" matches //mcp_infra/compositor:test_lifecycle/test.log
"test_lifecycle/test.xml" matches the XML output specifically
"compositor/test_lifecycle" matches //mcp_infra/compositor:test_lifecycle/test.log
When no match is found, the CLI prints available labels as hints.
Three kinds of file, three commands
Bazel files attached to the invocation itself, such as command.profile.gz, are BES
BuildToolLogs — use bbapi tool-log {list,cat,download}. They can be inline
(elapsed time, critical path, process stats) or bytestream-backed
(command.profile.gz); bbapi tool-log cat handles both.
Everything a target produced is bbapi artifact, in two kinds:
--kind test — outputs of a test action: test.log, test.xml, files under
test.outputs/.
--kind build — files in a completed target's output groups: a wheel, a
.skill, an oci_image's .json.sha256. Lint aspects contribute their own
groups, so filter on the GROUP column (default for a target's real
outputs, rules_lint_report / mypy / clippy_checks / rustfmt_checks for
the aspects).
Deviation from what BuildBuddy's web UI shows: the UI surfaces test artifacts
only. Build outputs reach the BES stream as TargetComplete → output group →
NamedSetOfFiles, and bbapi walks that graph.
--json carries each file's digest and size as BES reports them. For a
single-file release the digest is the content identity, so a caller can compare
against a published tag without fetching the bytes.
Gotcha: identify a file by pathPrefix + name, never name alone. A
source file has an empty prefix while the generated file of the same name lives
under bazel-out/k8-fastbuild/bin, and a configuration transition writes to
bazel-out/k8-fastbuild-ST-<hash>/bin. On devel's //... sweep four names
collide across prefixes.
For CI phase profiling, start with:
bb view <runner-or-child-invocation> --lines=200000
bbapi invocation <runner-invocation>
bbapi tool-log list <runner-invocation>
bbapi tool-log cat <child-invocation> "process stats"
bbapi tool-log download <runner-invocation> command.profile.gz --all -o profiles/
The runner log line Syncing existing repo... identifies a warm outer bb remote runner
workspace, but it does not by itself prove the inner Bazel analysis cache survived. Check
Bazel's package/configuration counts, elapsed time, targetConfiguredCount, and
command.profile.gz. Treat targetConfiguredCount as the configured graph size/result
count, not by itself proof that those configured targets were recomputed; profile markers,
discarding analysis cache warnings, and time-to-first-action are better recomputation
signals.
Bisecting Test Failures with Target History
When a test is failing and you need to find the commit that broke it, use target
history instead of git bisect — BuildBuddy already has all the results:
bbapi target history --failures-only --label //path/to:test_target
git log --oneline <last-pass-commit>..<first-fail-commit>
bbapi target log <first-failing-invocation-id> test_target
This is much faster than git bisect because it doesn't require re-running the
test — the results are already in BuildBuddy's database.
Diagnosing Executor Environments
Use bb execute to run one-off commands directly on a BuildBuddy executor to probe the container image, check installed tools, verify library paths, etc. Useful when builds fail due to missing dependencies or environment issues.
bb execute \
-exec_properties=container-image=docker://ghcr.io/agentydragon/rbe-worker:nix-devtools \
-- bash -c 'gcc --version; python3 --version; ldd --version | head -1'
bb execute \
-exec_properties=container-image=docker://ghcr.io/agentydragon/rbe-worker:latest \
-- bash -c 'find / -name "libstdc++.so*" 2>/dev/null'
bb execute \
-exec_properties=container-image=docker://ghcr.io/agentydragon/rbe-worker:latest \
-- bash -c 'python3 -m pip install --dry-run some-package==1.0'
bb execute runs on the default executor image (Ubuntu 16.04, glibc 2.23) unless you specify -exec_properties=container-image=.... Use -exec_properties=workload-isolation-type=firecracker to test with Firecracker isolation.
Interactive debugging with bb ssh
For interactive debugging, start an SSH server on a BuildBuddy executor:
bb ssh-server my-debug-session
bb ssh my-debug-session
This gives a full shell on the executor for investigating build failures, inspecting the filesystem, testing commands interactively, etc.
BuildBuddy Concepts
Group ID: BuildBuddy's organization identifier (e.g., GR7963402054611859571).
Scopes API queries to the org's data. Auto-detected by bbapi from a recent invocation's
ACL — no manual configuration needed.
Workflow ID: For repos using buildbuddy.yaml + GitHub app, workflow IDs are synthetic:
WF#GitRepository:{group_id}:{repo_url}. The bbapi workflow run command auto-constructs
this from the detected group_id and repo URL. GetWorkflows returns empty for these repos
(it only lists explicitly created workflows).
Raw API Fallback
If bbapi is not available, use the Twirp JSON API at app.buildbuddy.io directly
with curl. Read <../../client.go> for how the CLI talks to the API
(Twirp JSON over HTTP). The API key comes from BUILDBUDDY_API_KEY env var, or
parse it from ~/.config/bazel/buildbuddy.bazelrc (x-buildbuddy-api-key=...).
Proto definitions for request/response schemas:
Known Limitations
Fork PRs don't have BuildBuddy invocations. GitHub Actions does not pass
BUILDBUDDY_API_KEY to workflows triggered by fork pull requests (head repo !=
base repo). As a result, bazel-check and bazel-test are skipped entirely on
fork PRs (see #787).
When investigating a failed fork PR, BuildBuddy has no record of the run — check
GitHub Actions logs directly instead.