Skip to content

Feature/executor error retry - #493

Merged
qdaxb merged 6 commits into
mainfrom
feature/executor-error-retry
Feb 6, 2026
Merged

qdaxb merged 6 commits into
mainfrom
feature/executor-error-retry

Conversation

@FicoHu

@FicoHu FicoHu commented Feb 6, 2026 •

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

Release Notes

  • Bug Fixes
    • Enhanced session resumption logic to correctly track and restore Claude SDK session states during retries, improving reliability of interrupted operation recovery.
    • Improved handling of residual interrupts and error-recovery scenarios for better operation resilience.

yunpeng7 and others added 6 commits February 6, 2026 18:56
Add automatic retry capability when Claude SDK returns retryable errors
like error_during_execution or error_max_turns. The retry mechanism:

- Closes current client while preserving session_id
- Creates new client with --resume option to restore session
- Sends "Continue" message to resume execution
- Supports up to 3 retry attempts before failing

This improves task reliability by recovering from transient errors.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
error_max_turns indicates the task exceeded turn limits, which means
the task is too complex. Retrying will likely hit the same limit again.
Only error_during_execution (transient errors) should be retried.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add Chinese and English translations for:
- error_subtype_retry: Shown when retrying recoverable errors
- error_subtype_max_retries: Shown when max retries reached

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Use more descriptive retry message to prompt Claude to continue
- Fix session_id handling in retry loop to use self.session_id
- Prevent _create_and_connect_client from overwriting resume option
- Add detailed logging for retry debugging

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The RETRY_WITH_RESUME mechanism was using our internal session key
(task_id:bot_id format like "225172:100209") instead of the actual
Claude SDK session_id (UUID format like "024aee0c-019d-44d9-bce9-e91b96eadf9e").

Changes:
- _process_result_message now returns tuple ("RETRY_WITH_RESUME", actual_session_id)
  where actual_session_id is msg.session_id from Claude SDK
- process_response propagates the tuple to the caller
- ClaudeCodeAgent extracts the UUID from the tuple and uses it for resume

This fixes the "Command failed with exit code 1" error after session resume
because Claude SDK's resume option requires the actual UUID, not our internal key.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Feb 6, 2026 •

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

This PR refactors the Claude code execution retry-with-resume flow to properly pass and utilize actual Claude session IDs. The response processor now returns a tuple containing the session ID instead of a plain string, allowing the agent to recreate the client with the correct session for resumption.

Changes

Cohort / File(s) Summary
Resume Retry Signaling
executor/agents/claude_code/response_processor.py
Extended return type hints to support Tuple[str, str] for session IDs. Introduced RETRY_RESIDUAL case for residual interrupts. Modified retry signaling to return ("RETRY_WITH_RESUME", actual_session_id) tuple with extracted Claude session IDs and updated logging to reflect actual session context during resume operations.
Client Recreation with Session
executor/agents/claude_code/claude_code_agent.py
Updated RETRY\_WITH\_RESUME detection to extract session ID from tuple return value. Sets self.options["resume"] to the extracted actual Claude session ID before client recreation, ensuring proper SDK session resumption. Removed previous locally-stored resume value approach in favor of tuple-based session ID passing.

Sequence Diagram(s)

sequenceDiagram
    participant Agent as Claude<br/>Code Agent
    participant Processor as Response<br/>Processor
    participant SDK as Claude<br/>SDK Client
    
    Agent->>Processor: process_response(response, session_id)
    
    alt Resume Required
        Processor->>Processor: Detect retry condition<br/>Extract actual_session_id
        Processor-->>Agent: ("RETRY_WITH_RESUME",<br/>actual_session_id)
        
        Agent->>Agent: Extract tuple<br/>Set resume option
        Agent->>SDK: _create_and_connect_client()<br/>with resume=actual_session_id
        SDK-->>Agent: New client (resumed session)
        Agent->>SDK: Send continue message<br/>to session_id
    else Residual Interrupt
        Processor-->>Agent: "RETRY_RESIDUAL"
        Agent->>Agent: Queue message for resend
    else Task Complete
        Processor-->>Agent: TaskStatus result
    end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

Suggested reviewers

  • qdaxb

Poem

🐰 A tuple hops where strings once ran,
Session IDs flow through the plan,
Resume with grace, no session lost—
The agent and processor have crossed,
Where retry means resuming true! 🌟

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'Feature/executor error retry' is vague and uses a generic pattern typical of branch names rather than describing the actual changes made in the pull request. Replace the generic title with a specific description of the main change, such as 'Improve Claude agent retry handling with session ID propagation' or 'Add RETRY_RESIDUAL support and fix resume session ID handling'.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/executor-error-retry

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 and usage tips.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
executor/agents/claude_code/response_processor.py (1)

877-901: ⚠️ Potential issue | 🟠 Major

Guard against passing internal session key to Claude SDK resume parameter.

If msg.session_id is None, actual_claude_session_id falls back to the session_id parameter, which can be an internal key format (e.g., "task-123" or "123:456"). This is not a valid Claude UUID and would cause the resume to fail. Since a valid Claude session ID is required for proper resume, avoid returning RETRY_WITH_RESUME when msg.session_id is None.

Suggested fix
-            # Get actual Claude session ID (UUID) for resume
-            # msg.session_id is the Claude UUID, session_id parameter is our internal key
-            actual_claude_session_id = msg.session_id or session_id
+            # Get actual Claude session ID (UUID) for resume
+            # msg.session_id is the Claude UUID, session_id parameter is our internal key
+            if not msg.session_id:
+                logger.warning(
+                    f"No Claude session ID available for resume, "
+                    f"cannot retry error subtype {msg.subtype}"
+                )
+                # Fall through to fail the task since we can't resume without a valid session
+            else:
+                actual_claude_session_id = msg.session_id
🧹 Nitpick comments (2)
executor/agents/claude_code/response_processor.py (1)

269-269: Minor inconsistency: lowercase tuple vs imported Tuple.

Line 269 uses tuple[bool, str] (PEP 604 / Python 3.9+ syntax), while the rest of the file uses Tuple from typing (line 5). This works fine on Python 3.9+ but is inconsistent. Consider unifying to one style.

Use `Tuple` for consistency
-def _handle_user_message(msg: UserMessage, thinking_manager=None) -> tuple[bool, str]:
+def _handle_user_message(msg: UserMessage, thinking_manager=None) -> Tuple[bool, str]:
executor/agents/claude_code/claude_code_agent.py (1)

738-753: Stale resume option persists in self.options after retry completes.

After self.options["resume"] = actual_claude_session_id on line 740, this key is never cleaned up when the retry loop exits (success or failure). While the current task lifecycle likely prevents reuse issues, this is defensive-coding debt:

  • _create_and_connect_client (line 805) guards with if "resume" not in self.options, so a stale resume key would prevent loading a fresh saved session ID on any subsequent client creation for this agent instance.

Consider cleaning up after the retry loop exits:

Clean up resume option after retry loop
                 # Continue loop to process response
                 continue

             # Normal completion or non-retryable failure
             break

+        # Clean up retry-specific options
+        self.options.pop("resume", None)
+
         if result is None:

@qdaxb
qdaxb merged commit 1fea589 into main Feb 6, 2026
14 checks passed
@qdaxb
qdaxb deleted the feature/executor-error-retry branch February 6, 2026 14:53
@coderabbitai coderabbitai Bot mentioned this pull request Feb 9, 2026
10 tasks done
maquan0927 pushed a commit to maquan0927/Wegent that referenced this pull request Feb 11, 2026
* feat(executor): add retry mechanism for error_during_execution

Add automatic retry capability when Claude SDK returns retryable errors
like error_during_execution or error_max_turns. The retry mechanism:

- Closes current client while preserving session_id
- Creates new client with --resume option to restore session
- Sends "Continue" message to resume execution
- Supports up to 3 retry attempts before failing

This improves task reliability by recovering from transient errors.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(executor): remove error_max_turns from retryable errors

error_max_turns indicates the task exceeded turn limits, which means
the task is too complex. Retrying will likely hit the same limit again.
Only error_during_execution (transient errors) should be retried.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(frontend): add i18n translations for error retry mechanism

Add Chinese and English translations for:
- error_subtype_retry: Shown when retrying recoverable errors
- error_subtype_max_retries: Shown when max retries reached

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(executor): improve error retry mechanism

- Use more descriptive retry message to prompt Claude to continue
- Fix session_id handling in retry loop to use self.session_id
- Prevent _create_and_connect_client from overwriting resume option
- Add detailed logging for retry debugging

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(executor): use Claude SDK session_id (UUID) for RETRY_WITH_RESUME

The RETRY_WITH_RESUME mechanism was using our internal session key
(task_id:bot_id format like "225172:100209") instead of the actual
Claude SDK session_id (UUID format like "024aee0c-019d-44d9-bce9-e91b96eadf9e").

Changes:
- _process_result_message now returns tuple ("RETRY_WITH_RESUME", actual_session_id)
  where actual_session_id is msg.session_id from Claude SDK
- process_response propagates the tuple to the caller
- ClaudeCodeAgent extracts the UUID from the tuple and uses it for resume

This fixes the "Command failed with exit code 1" error after session resume
because Claude SDK's resume option requires the actual UUID, not our internal key.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: yunpeng7 <yunpeng7@staff.weibo.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
fengkuizhi pushed a commit that referenced this pull request Mar 3, 2026
Feature/executor error retry (#493)

See merge request weibo_rd/common/wecode/wegent!1413
@coderabbitai coderabbitai Bot mentioned this pull request Mar 6, 2026
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