Skip to content

fix: honour store_failed for negative exit codes and daemon mode#3495

Open
jerry7991 wants to merge 3 commits into
atuinsh:mainfrom
jerry7991:fix/store-failed-respects-all-non-zero-exits
Open

fix: honour store_failed for negative exit codes and daemon mode#3495
jerry7991 wants to merge 3 commits into
atuinsh:mainfrom
jerry7991:fix/store-failed-respects-all-non-zero-exits

Conversation

@jerry7991

Copy link
Copy Markdown

Summary

store_failed = false was still keeping two classes of failed commands in history:

  1. Signal kills (negative exit codes)crates/atuin/src/command/client/history.rs:511 used exit > 0, so anything that came in as a negative exit (e.g. Ctrl+C-interrupted runs, which atuin already supports recording per fix: record negative exit codes #821) slipped past the filter.
  2. Daemon mode — the daemon's EndHistory RPC handler never consulted store_failed, so users running daemon.enabled = true had every non-zero exit persisted regardless of their setting.

Changes

  • handle_end: change the predicate to exit != 0 so negative exit codes are also dropped.
  • atuin-daemon history component: check handle.settings().await.store_failed inside end_history; when it's false and the exit is non-zero, remove the entry from the running map and return early without writing to the local DB or pushing to the record store.
  • Add four unit tests covering (store_failed, exit) combinations: failed+disabled, signal-killed+disabled, success+disabled, failed+enabled.
  • Touch up the store_failed config doc to mention signal kills and daemon mode.

Why

Reported by a user who had store_failed = false but still saw failed commands appearing in atuin search. The behaviour was due to the two gaps above. The local-path bug was introduced in #2284 when the original != was tightened to > on the (incorrect) assumption that exit codes are always 0–255; the daemon-path gap was there from the original daemon implementation.

Test plan

  • cargo test -p atuin --bin atuin handle_end — 4 new tests pass
  • cargo test -p atuin --bin atuin — full atuin suite green (218 passed)
  • cargo test -p atuin-daemon — daemon lifecycle suite green (5 passed)
  • cargo clippy -p atuin -p atuin-daemon --no-deps — clean
  • cargo fmt --check -p atuin -p atuin-daemon — clean

The `store_failed = false` setting was leaking two classes of failed
commands into history.

1. Commands killed by a signal record a negative exit code (PR atuinsh#821),
   but `handle_end` only filtered when `exit > 0`, so signal kills like
   Ctrl+C-interrupted runs were kept.
2. The daemon's `end_history` RPC never consulted `store_failed` at all,
   so when `daemon.enabled = true` every failed command was persisted
   regardless of the user's preference.

Switch the local check to `exit != 0` and add the same gate inside the
daemon's `end_history` handler (it already has access to live settings
via `DaemonHandle::settings`). Cover both paths with unit tests for
exit code 0, positive, and negative.
@github-actions

Copy link
Copy Markdown
Contributor

Fossier: Manual Review Requested

@jerry7991 is a new contributor. A maintainer should review this PR before merging.

Score Breakdown

Total Score: 67.1/100 | Confidence: 100% | Outcome: REVIEW

Signal Value Score Weight
account_age 2049 1.00 0.09
public_repos 32 1.00 0.05
contribution_history 32 0.16 0.05
follower_ratio 0.7 0.35 0.05
bot_signals False 0.50 0.04
open_prs_elsewhere 2 0.75 0.09
closed_prs_elsewhere 0 1.00 0.10
merged_prs_elsewhere 13 1.00 0.08
prior_interaction 0 0.00 0.08
activity_velocity 1 1.00 0.08
pr_content ... 1.00 0.08
commit_email no_email 0.50 0.04
pr_description ... 0.55 0.05
repo_stars 29796 0.30 0.04
org_membership 0 0.20 0.03
commit_verification ... 0.30 0.04
contributor_stars 26 0.52 0.04

@greptile-apps

greptile-apps Bot commented May 20, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR makes store_failed = false apply consistently to non-zero command exits. The main changes are:

  • Treat negative exit codes as failed in the local history end path.
  • Drop failed daemon-mode history entries before DB and record-store writes.
  • Add unit coverage for failed, signal-killed, successful, and allowed-failure cases.
  • Update the config docs to mention signal kills and daemon mode.

Confidence Score: 5/5

This looks safe to merge.

  • No blocking issues found in the changed code.
  • The daemon path removes the in-memory running entry before returning.
  • The local path reuses the existing soft-delete behavior for failed commands.

Important Files Changed

Filename Overview
crates/atuin/src/command/client/history.rs Updates the local failed-command filter and adds focused tests for store_failed behavior.
crates/atuin-daemon/src/components/history.rs Adds daemon-side filtering so non-zero exits are not persisted when failed-command storage is disabled.
docs/docs/configuration/config.md Clarifies that store_failed = false applies to all non-zero exits and daemon mode.

Reviews (1): Last reviewed commit: "fix: honour store_failed for negative ex..." | Re-trigger Greptile

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant