aspect-build / aspect-build/rules_lint
[Bug]: ruff_action() in --fix mode never surfaces ruff's stderr, so failures are just an unexplained exit code
- Dominant language
- Starlark
- Stars
- 154
- Forks
- 125
- Avg merge
- 3d 21h
- Merged PRs (30d)
- 20
Description
### What happened?
Ran ruff in lint-and-fix mode and got an unexplained error with empty output. Investigation revealed ruff was outputting on stderr and that was not wired up.
### Version
2.7.2
### How to reproduce
```shell
As above
```
### Any other information?
When lint_ruff_aspect runs in fix mode (--fix), ruff_action() in lint/ruff.bzl calls run_patcher() without a stderr argument. If ruff fails inside the patcher sandbox (e.g. a bad env var, a crash, an unexpected argument), the only signal that survives is a non-zero exit code : ruff's actual diagnostic, written to stderr, is discarded.
This is surprising because run_patcher() (lint/private/patcher_action.bzl) already fully supports capturing stderr via a stderr param, wiring JS_BINARY__STDERR_OUTPUT_FILE and adding it as a declared output. Other callers just aren't taking advantage of it for ruff.
Repro
1. Configure lint_ruff_aspect with fix mode enabled.
2. Cause ruff to fail inside the patcher's sandboxed environment in a way that only prints to stderr and exits non-zero (e.g. any exit-2 usage/config error : the sandbox runs with a near-empty env, so anything relying on env state is a likely trigger).
3. Run the aspect / bazel build --aspects=...fix....
Expected: the action fails with ruff's stderr diagnostic visible.
Actual: the action fails with only an exit code — no indication of what went wrong.
Root cause
In lint/ruff.bzl, ruff_action():
```
def ruff_action(ctx, executable, srcs, config, stdout, exit_code = None, env = {}, patch = None):
...
run_patcher(
ctx,
ctx.executable,
inputs = inputs,
args = args,
files_to_diff = [s.path for s in srcs],
patch_cfg_env = env,
patch_out = patch,
tools = [executable],
stdout = stdout,
exit_code = exit_code,
env = env,
mnemonic = _MNEMONIC,
progress_message = "Fixing %{label} with Ruff",
)
```
No stderr is ever declared or passed through, even though run_patcher accepts one.
I confirmed this is still present on main as of 2026-08-17, not just the pinned v2.7.2 release.
Suggested fix
Add a stderr param to ruff_action(), forward it to run_patcher(), and declare a stderr output file in _ruff_aspect_impl when fix mode is active (analogous to how outputs.human.exit_code is declared).
Contributor guide
Research direction
Start in lint/ruff.bzl at ruff_action() and _ruff_aspect_impl, then read lint/private/patcher_action.bzl to follow run_patcher()'s existing stderr support. Reproduce the fix-mode failure described in the issue and verify that a failing Ruff action exposes its stderr diagnostic rather than only an exit code.
Written by the indexing model from the issue text.
Assessment
- Domain
- build-system
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100