Skip to content

fix: chatwidget was not honoring approval_id for an ExecApprovalRequestEvent#12746

Merged
bolinfest merged 1 commit intomainfrom
pr12746
Feb 25, 2026
Merged

fix: chatwidget was not honoring approval_id for an ExecApprovalRequestEvent#12746
bolinfest merged 1 commit intomainfrom
pr12746

Conversation

@bolinfest
Copy link
Copy Markdown
Collaborator

@bolinfest bolinfest commented Feb 25, 2026

Why

ExecApprovalRequestEvent can carry a distinct approval_id for subcommand approvals, including the execve-intercepted zsh-fork path.

The session registers the pending approval callback under approval_id when one is present, but ChatWidget was stashing call_id in the approval modal state. When the user approved the command in the TUI, the response was sent back with the wrong identifier, so the pending approval could not be matched and the approval callback would not resolve.

Note approval_id was introduced in #12051.

What changed

  • In tui/src/chatwidget.rs, ChatWidget now uses ExecApprovalRequestEvent::effective_approval_id() when constructing ApprovalRequest::Exec.
  • That preserves the existing behavior for normal shell and unified_exec approvals, where approval_id is absent and the effective id still falls back to call_id.
  • For subcommand approvals that provide a distinct approval_id, the TUI now sends back the same key that Session::request_command_approval() registered.

Verification

  • Traced the approval flow end to end to confirm the same effective approval id is now used on both sides of the round trip:
    • Session::request_command_approval() registers the pending callback under approval_id.unwrap_or(call_id).
    • ChatWidget now emits Op::ExecApproval with that same effective id.

Copy link
Copy Markdown
Contributor

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 69f91d03b6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".


let request = ApprovalRequest::Exec {
id: ev.call_id,
id: ev.effective_approval_id(),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Badge Keep replay-tracking key aligned with approval response ID

handle_exec_approval_now now sets ApprovalRequest::Exec.id to ev.effective_approval_id(), but pending interactive replay still indexes exec approvals by ev.call_id and later clears them using outbound Op::ExecApproval.id (codex-rs/tui/src/app/pending_interactive_replay.rs, note_event at lines 113-119 and note_outbound_op at lines 60-67). When approval_id differs from call_id (subcommand approvals), approving in the TUI no longer removes the tracked pending prompt, so should_replay_snapshot_event (lines 219-222) can replay an already-resolved approval after a thread/agent switch before TurnComplete arrives.

Useful? React with 👍 / 👎.

@bolinfest bolinfest merged commit ddfa032 into main Feb 25, 2026
31 of 33 checks passed
@bolinfest bolinfest deleted the pr12746 branch February 25, 2026 06:27
@github-actions github-actions bot locked and limited conversation to collaborators Feb 25, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants