Skip to content

fix(status): return error when daemon not found and improve test diagnostics#224

Merged
jdx merged 1 commit intomainfrom
fix/flaky-stop-test
Feb 10, 2026
Merged

fix(status): return error when daemon not found and improve test diagnostics#224
jdx merged 1 commit intomainfrom
fix/flaky-stop-test

Conversation

@jdx
Copy link
Owner

@jdx jdx commented Feb 10, 2026

Summary

  • pitchfork status <id> now returns a non-zero exit code when daemon is not found (was silently succeeding with exit 0)
  • wait_for_status test helper is more resilient under CI load: timeout increased 5s→10s, reads state file directly as fallback
  • On test failure, dumps full diagnostics (stderr, stdout, exit code, raw state file) to debug flaky CI

Fixes the flaky test_stop_already_stopped failure seen in CI where the daemon status returned None after stopping.

Test plan

  • All 127 tests pass locally
  • No new clippy/fmt warnings introduced
  • Verify CI passes on this PR

🤖 Generated with Claude Code


Note

Medium Risk
Changes pitchfork status to return an error when a daemon ID is missing, which may affect scripts relying on the previous zero-exit behavior. Test helper changes are low-risk but adjust timing and add state-file parsing that could mask underlying issues if misused.

Overview
pitchfork status <id> now fails fast: when the daemon ID is not found, the command returns an error (miette::bail!) instead of only logging a warning and exiting successfully.

E2E test flake hardening: wait_for_status now waits up to 10s (50×200ms), falls back to reading the daemon status directly from the on-disk state.toml, and emits detailed diagnostics (CLI stdout/stderr/exit code plus raw state file) on timeout.

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

…nostics

The `pitchfork status` command was silently succeeding (exit 0) when a
daemon wasn't found, making it impossible for callers to distinguish
"not found" from "found with status". Now it returns a non-zero exit
code with an error message.

Also improves the `wait_for_status` test helper to be more resilient
under CI load:
- Increased timeout from 5s to 10s
- Added direct state file reading as fallback (bypasses CLI)
- On failure, dumps full diagnostics: stderr, stdout, exit code, and
  raw state file contents for easier debugging of flaky CI failures

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings February 10, 2026 14:26
@gemini-code-assist
Copy link

Summary of Changes

Hello @jdx, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses a bug in the pitchfork status command's error handling and significantly improves the robustness and diagnostic capabilities of the test suite, particularly for CI environments. The changes ensure that the CLI command provides clearer feedback when a daemon is not found and enhance test stability by making status checks more resilient and providing detailed debugging information on failure.

Highlights

  • Error Handling: The pitchfork status <id> command now correctly returns a non-zero exit code and errors out when the specified daemon is not found, instead of silently succeeding.
  • Test Reliability: The wait_for_status test helper's timeout was increased from 5 seconds to 10 seconds to improve resilience under continuous integration (CI) load.
  • Test Diagnostics: A new fallback mechanism was added to wait_for_status to directly read the daemon's status from its state file on disk, bypassing CLI/IPC, for more robust status checks.
  • Debugging CI Failures: Upon test failure in wait_for_status, comprehensive diagnostics (CLI status, state file status, exit code, stdout, stderr, and raw state file contents) are now dumped to aid in debugging flaky CI issues.
Changelog
  • src/cli/status.rs
    • Replaced warn! with miette::bail! to propagate errors when a daemon is not found.
  • tests/common/mod.rs
    • Added get_daemon_status_from_state_file function to read daemon status directly from disk.
    • Increased wait_for_status retry count and timeout from 5s to 10s.
    • Implemented a fallback in wait_for_status to use direct state file reading if CLI status is not as expected.
    • Enhanced the panic message in wait_for_status to include detailed diagnostic information on test failure.
Activity
  • The author has confirmed that all 127 tests pass locally.
  • No new clippy or formatting warnings were introduced.
  • The PR description indicates it was generated with Claude Code, suggesting AI assistance in its creation.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Updates pitchfork status to fail when a daemon ID doesn’t exist, and strengthens test helpers to reduce CI flakiness with better retry logic and failure diagnostics.

Changes:

  • Make status <id> return an error (non-zero exit) when the daemon is not found.
  • Improve wait_for_status reliability by increasing timeout and adding a state-file fallback.
  • Expand failure diagnostics to include CLI output, exit code, and raw state file contents.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
tests/common/mod.rs Extends status polling logic and adds state-file fallback + richer panic diagnostics for CI failures.
src/cli/status.rs Changes “daemon not found” behavior from a warning + success to an error return.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +240 to +241
// Also try reading state file directly as fallback
let file_status = self.get_daemon_status_from_state_file(daemon_id);
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

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

The state file is read+parsed on every polling iteration even when the CLI is responding normally. To reduce filesystem I/O and TOML parsing overhead (especially under CI), consider only using the state-file fallback when the CLI status is None (or when the status command indicates a recoverable failure), rather than on every loop iteration.

Suggested change
// Also try reading state file directly as fallback
let file_status = self.get_daemon_status_from_state_file(daemon_id);
// Only fall back to reading the state file when the CLI status is unavailable.
let file_status = if status.is_none() {
self.get_daemon_status_from_state_file(daemon_id)
} else {
None
};

Copilot uses AI. Check for mistakes.
Comment on lines +257 to +262
CLI status: {status:?}\n\
State file status: {file_status:?}\n\
Status exit code: {}\n\
Status stdout: {status_stdout}\n\
Status stderr: {status_stderr}\n\
State file ({}):\n{state_contents}",
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

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

The string literal uses \\\n line continuations with indentation, which will embed leading spaces into the panic output and can make diagnostics harder to read/copy. Consider constructing the message without indentation (e.g., by left-aligning continuation lines or building the message via a dedicated formatter) so the emitted diagnostics are clean and consistent.

Suggested change
CLI status: {status:?}\n\
State file status: {file_status:?}\n\
Status exit code: {}\n\
Status stdout: {status_stdout}\n\
Status stderr: {status_stderr}\n\
State file ({}):\n{state_contents}",
CLI status: {status:?}\n\
State file status: {file_status:?}\n\
Status exit code: {}\n\
Status stdout: {status_stdout}\n\
Status stderr: {status_stderr}\n\
State file ({}):\n{state_contents}",

Copilot uses AI. Check for mistakes.
println!("Status: {}", daemon.status.style());
} else {
warn!("Daemon {} not found", self.id);
miette::bail!("Daemon {} not found", self.id);
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

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

This changes user-visible behavior (non-zero exit + error) when the daemon ID is missing. Add a test that asserts pitchfork status <missing-id> returns a failure exit code and includes the expected error message (or a stable substring) to prevent regressions.

Copilot uses AI. Check for mistakes.
Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces valuable improvements to both the pitchfork status command and the end-to-end test suite. The change to pitchfork status to return a non-zero exit code when a daemon is not found is a crucial correctness fix, providing clearer feedback to users and scripts. The enhancements to the wait_for_status test helper, including increased timeouts, a direct state file fallback, and comprehensive diagnostic logging on failure, are excellent for improving test reliability and debugging flaky CI issues. These changes directly address the problems outlined in the pull request description and contribute positively to the project's stability and maintainability. The implementation is clean and well-justified.

@jdx jdx merged commit 702c747 into main Feb 10, 2026
5 checks passed
@jdx jdx deleted the fix/flaky-stop-test branch February 10, 2026 14:36
@jdx jdx mentioned this pull request Feb 10, 2026
jdx added a commit that referenced this pull request Feb 11, 2026
## 🤖 New release

* `pitchfork-cli`: 1.3.0 -> 1.4.0

<details><summary><i><b>Changelog</b></i></summary><p>

<blockquote>

## [1.4.0](v1.3.0...v1.4.0) -
2026-02-11

### Added

- *(config)* add `dir` and `env` fields for daemons
([#227](#227))

### Fixed

- *(status)* return error when daemon not found and improve test
diagnostics ([#224](#224))
</blockquote>


</p></details>

---
This PR was generated with
[release-plz](https://github.com/release-plz/release-plz/).

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Release metadata-only change (version bump and changelog updates) with
no functional code modifications in this PR.
> 
> **Overview**
> Updates the crate version from `1.3.0` to `1.4.0` (including
`Cargo.lock`) and adds a new `CHANGELOG.md` entry for the `v1.4.0`
release.
> 
> The release notes call out new daemon config fields (`dir`, `env`) and
a `status` fix to error when a daemon is not found (plus improved test
diagnostics).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
09bdfb8. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
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.

2 participants