Skip to content

Reset log selection at context boundaries instead of clamping on read - #700

Open
jvanbuel wants to merge 1 commit into
claude/airflow-dag-list-cache-bug-axik1pfrom
claude/reset-log-state-on-boundaries
Open

Reset log selection at context boundaries instead of clamping on read#700
jvanbuel wants to merge 1 commit into
claude/airflow-dag-list-cache-bug-axik1pfrom
claude/reset-log-state-on-boundaries

Conversation

@jvanbuel

Copy link
Copy Markdown
Owner

Stacked on #695. Both touch clear_state(), so this targets that branch rather than main. GitHub will retarget it to main automatically once #695 merges. Review #695 first.

Two halves of the same problem: log view state outliving the context it belonged to.

1. clear_state() left log state behind

Switching environments cleared logs.all but left logs.current (which try is selected) and logs.scroll_mode pointing into the previous environment's tries. Land on a task with two tries carrying current = 3 from before, and you open on try 2 instead of try 1; a deep Manual { position } scroll leaks into the next log you view.

The codebase already knew how to do this — state/context.rs does exactly the right thing when the task context changes:

if is_new_context {
    self.logs.current = 0;
    self.logs.reset_scroll();
}

clear_state() now uses the same two lines. LogModel::reset_scroll() is documented "used when navigating to a new context" and simply wasn't being called on the environment-switch path.

2. current_index() clamped on read instead of fixing the write

fn current_index(&self) -> usize {
    self.current % self.all.len().max(1)
}

This re-derived a valid index on every single read, papering over a stale current rather than correcting it. update_logs now clamps when it writes the list, so current is always valid and the three readers use it directly. current_index() is gone.

Clamping also beats wrapping on the merits: after the try list shrinks you want the newest try, not whichever one modular arithmetic happens to land on. With current = 4 and three tries, wrapping gives try 2; clamping gives try 3.

Test changes

current_index_wraps_when_selection_exceeds_len encoded the workaround as intended behavior, so it's replaced by two tests on the new contract — one for the clamp, one for the empty list. The existing open_ui_with_empty_logs_does_not_panic regression test still passes; with the modulo gone there is no division left to panic on.

Verification

cargo test --workspace --lib --bins (95 passing), cargo clippy --workspace --all-targets --all-features -- -D warnings, and cargo fmt --all --check all clean.

🤖 Generated with Claude Code

https://claude.ai/code/session_0127jzUgqqy8JVX5RydfQxh8


Generated by Claude Code

Two halves of the same problem.

clear_state() dropped the log data on an environment switch but left
logs.current and the scroll mode pointing into the previous
environment's tries. state/context.rs already does the right thing when
the task context changes; clear_state now uses the same two lines.

current_index() re-derived a valid index on every read via
'self.current % self.all.len().max(1)', papering over a stale value
rather than fixing it. update_logs now clamps current when it writes the
list, so current is always valid and readers use it directly. Clamping
also beats wrapping on the merits: after a shrink you want the newest
try, not whichever one modular arithmetic lands on.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0127jzUgqqy8JVX5RydfQxh8
@coderabbitai

coderabbitai Bot commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 93b7aa14-345a-4735-945d-cf3625229d16

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/reset-log-state-on-boundaries

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

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