Skip to content

Comments

fix: display stderr when check_list_files returns empty list#334

Merged
jdx merged 1 commit intomainfrom
fix-check-list-files-empty-stderr
Oct 3, 2025
Merged

fix: display stderr when check_list_files returns empty list#334
jdx merged 1 commit intomainfrom
fix-check-list-files-empty-stderr

Conversation

@jdx
Copy link
Owner

@jdx jdx commented Oct 3, 2025

Summary

When check_list_files commands (like gofmt) encounter syntax errors, they often write errors to stderr but return an empty file list on stdout. Previously, hk would then run the fix command with no files, leading to confusing errors like "cannot use -w with standard input".

This change detects when check_list_files returns an empty list but has stderr output, and fails immediately with the actual error messages displayed to the user.

Example

Before: User sees misleading error

✗ go-fmt – ERROR
go-fmt stderr:
error: cannot use -w with standard input

After: User sees actual Go syntax errors

✗ go-fmt – ERROR
go-fmt: check_list_files returned no files and produced errors:
deploys/v2/internal/gate/deploywindow/gate.go:108:26: string literal not terminated
deploys/v2/internal/gate/deploywindow/gate.go:109:4: expected operand, found '%'
...

Changes

  • Add stderr field to CheckListFailed error type
  • Check for empty stdout + non-empty stderr in successful check_list_files runs
  • Display stderr when check_first fails with empty file list
  • Add comprehensive test suite covering all scenarios

Test Plan

Added test/check_list_files_empty_with_stderr.bats with 3 tests:

  • ✅ Empty file list with stderr → fails and displays errors
  • ✅ Empty file list without stderr → succeeds (files already formatted)
  • ✅ Non-empty file list with stderr → processes files (warnings are OK)

All tests pass.

Related Issue

Fixes the issue reported where Go syntax errors were hidden behind misleading gofmt error messages.


Note

Propagates and displays stderr when check_list_files yields no files (empty stdout), failing early and adding tests to cover empty/no-empty combinations.

  • Core behavior:
    • Add stderr to Error::CheckListFailed in src/error.rs.
    • In src/step.rs:
      • Treat check_list_files success with empty stdout and non-empty stderr as an error, returning Error::CheckListFailed { stdout, stderr }.
      • When check_first fails with CheckListFailed, filter files; if none remain and stderr exists, fail early, surfacing stderr.
      • Populate stderr on script failure for CheckListFailed.
  • Tests:
    • Add test/check_list_files_empty_with_stderr.bats covering:
      • Empty list + stderr → fail and display errors.
      • Empty list + no stderr → succeed (no files to format).
      • Non-empty list + stderr → proceed with files (warnings).

Written by Cursor Bugbot for commit befaa71. This will update automatically on new commits. Configure here.

When check_list_files commands (like gofmt) encounter syntax errors,
they often write errors to stderr but return an empty file list on
stdout. Previously, hk would then run the fix command with no files,
leading to confusing errors like "cannot use -w with standard input".

This change detects when check_list_files returns an empty list but
has stderr output, and fails immediately with the actual error messages
displayed to the user.

Changes:
- Add stderr field to CheckListFailed error type
- Check for empty stdout + non-empty stderr in successful check_list_files runs
- Display stderr when check_first fails with empty file list
- Add comprehensive test suite covering all scenarios

Fixes the issue where Go syntax errors were hidden and users only saw
misleading "cannot use -w with standard input" errors.
if files.is_empty() && !stderr.trim().is_empty() {
error!("{step}: check_list_files returned no files and produced errors:\n{}", stderr);
return Err(eyre!("check_list_files failed with errors:\n{}", stderr));
}
Copy link

Choose a reason for hiding this comment

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

Bug: Empty Filtered List Causes False Error

The check_list_files error handling incorrectly fails when files are filtered out, resulting in an empty file list. If stderr is also present, the system misinterprets the empty filtered list as a failure, even if the original stdout from check_list_files was valid.

Fix in Cursor Fix in Web

@jdx jdx enabled auto-merge (squash) October 3, 2025 23:33
@jdx jdx merged commit ee2830e into main Oct 3, 2025
10 checks passed
@jdx jdx deleted the fix-check-list-files-empty-stderr branch October 3, 2025 23:33
@jdx jdx mentioned this pull request Oct 3, 2025
jdx added a commit that referenced this pull request Oct 5, 2025
## [1.17.0](https://github.com/jdx/hk/compare/v1.16.0..v1.17.0) -
2025-10-05

### 🚀 Features

- Add hk util trailing-whitespace command by
[@jdx](https://github.com/jdx) in
[#319](#319)
- add mixed_line_ending builtin by [@jdx](https://github.com/jdx) in
[#324](#324)
- add check_symlinks builtin by [@jdx](https://github.com/jdx) in
[#326](#326)
- add check_executables_have_shebangs builtin by
[@jdx](https://github.com/jdx) in
[#325](#325)
- Add check-merge-conflict util command and builtin by
[@jdx](https://github.com/jdx) in
[#322](#322)
- add check_case_conflict builtin by [@jdx](https://github.com/jdx) in
[#323](#323)
- add detect_private_key builtin by [@jdx](https://github.com/jdx) in
[#332](#332)
- add check_added_large_files builtin by [@jdx](https://github.com/jdx)
in [#329](#329)
- add python_debug_statements builtin by [@jdx](https://github.com/jdx)
in [#331](#331)
- add python_check_ast builtin by [@jdx](https://github.com/jdx) in
[#330](#330)
- add no_commit_to_branch builtin by [@jdx](https://github.com/jdx) in
[#333](#333)
- add check_byte_order_marker and fix_byte_order_marker builtins by
[@jdx](https://github.com/jdx) in
[#328](#328)
- add regex pattern support for glob and exclude by
[@jdx](https://github.com/jdx) in
[#336](#336)
- automatically batch large file lists to prevent ARG_MAX errors by
[@jdx](https://github.com/jdx) in
[#338](#338)

### 🐛 Bug Fixes

- Add validation for stage attribute requiring fix command by
[@jdx](https://github.com/jdx) in
[#327](#327)
- display stderr when check_list_files returns empty list by
[@jdx](https://github.com/jdx) in
[#334](#334)
- added new builtins to Builtins.pkl by [@jdx](https://github.com/jdx)
in
[b8a2b17](b8a2b17)
- enable experimental settings in mise.toml for swift support by
[@jdx](https://github.com/jdx) in
[#342](#342)
- correct airflow migration test to expect local imports by
[@jdx](https://github.com/jdx) in
[#343](#343)
- make final CI check always run and fail if dependencies fail by
[@jdx](https://github.com/jdx) in
[#344](#344)
- add ruff format to ruff builtin by [@jdx](https://github.com/jdx) in
[#340](#340)

### 🚜 Refactor

- Split util module into separate files by
[@jdx](https://github.com/jdx) in
[#321](#321)

### 🛡️ Security

- migrate pre-commit by [@jdx](https://github.com/jdx) in
[#318](#318)

### 🔍 Other Changes

- split CI runs into parallel jobs and add docs-sync mise task by
[@jdx](https://github.com/jdx) in
[#337](#337)
- remove v0 pkl files from docs/public by [@jdx](https://github.com/jdx)
in [#341](#341)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Release 1.17.0 with new migrate command, many util subcommands,
refreshed docs, and dependency updates.
> 
> - **Version**: bump `hk` to `1.17.0` (Cargo.toml, usage specs, docs).
> - **CLI**:
> - **New Command**: `migrate pre-commit` with flags (`--config`,
`--output`, `--force`, `--hk-pkl-root`).
> - **Util Subcommands**: add `check-added-large-files`,
`check-byte-order-marker`, `fix-byte-order-marker`,
`check-case-conflict`, `check-executables-have-shebangs`,
`check-merge-conflict`, `check-symlinks`, `detect-private-key`,
`end-of-file-fixer`, `mixed-line-ending`, `no-commit-to-branch`,
`python-check-ast`, `python-debug-statements`, `trailing-whitespace`.
> - **Docs**:
> - Update `docs/cli/index.md`, regenerate `docs/cli/commands.json`, and
`hk.usage.kdl`.
>   - Split `util` docs into per-command pages and add `migrate` docs.
> - **Dependencies**: update `Cargo.lock` crate versions and set `hk`
crate version to `1.17.0`.
> - **Changelog**: add `CHANGELOG.md` entry for `1.17.0` with
features/bug fixes.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
75b972a. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

Co-authored-by: mise-en-dev <[email protected]>
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.

1 participant