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

Open
#973 0 comments 0 reactions 0 assignees View on GitHub
bug
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.