Files
Doomsday_Survival_Manual/skills/retry-on-fail/SKILL.md

5.9 KiB

name, description
name description
retry-on-fail Automatically stop executing any operation if the failure retry count exceeds 5 times. Use when Codex needs to perform repeated operations with automatic backoff and fail-safe behavior, such as network requests, file operations, or API calls that may temporarily fail.

Retry on Fail

This skill provides guidance for implementing automatic retry logic with a maximum of 5 attempts before stopping execution.

About the Skill

The retry-on-fail skill ensures robust operation by automatically retrying failed actions up to 5 times, then halting execution if all retries are exhausted. This prevents infinite loops and helps identify persistent failures that need manual intervention.

When to Use This Skill

Use this skill when:

  • Performing network requests (HTTP calls, DNS lookups)
  • Executing file operations that may fail temporarily (write, read, delete)
  • Making API calls with potential rate limits or timeouts
  • Running commands in shell environments where transient errors occur
  • Any operation where temporary failures are expected but persistent failures should stop execution

Retry Behavior

  • Maximum attempts: 5 retries total (including the initial attempt = 6 total tries)
  • Backoff strategy: Exponential backoff with increasing delays between retries
  • Failure detection: Based on error codes, HTTP status codes >= 400, or non-zero exit codes
  • Stopping condition: After 5 failed attempts, execution stops and an error is reported

Core Principles

Concise is Key

The retry logic should be minimal and focused. Include only the essential code for:

  1. Attempting the operation
  2. Checking if it succeeded
  3. Implementing backoff delay
  4. Counting failures
  5. Stopping after 5 attempts

Set Appropriate Degrees of Freedom

Use a fixed maximum retry count (5) for consistency across all operations. This provides predictable behavior and makes debugging easier when persistent failures occur.

Anatomy of a Skill

Every skill consists of a required SKILL.md file:

retry-on-fail/
└── SKILL.md (required)
    ├── YAML frontmatter metadata (required)
    │   ├── name: retry-on-fail
    │   └── description: [as above]
    └── Markdown instructions (required)

Skill Implementation Pattern

Retry Logic Structure

The core retry mechanism follows this pattern:

  1. Initialize: Set attempt_count = 0, max_attempts = 5
  2. Loop: While attempt_count < max_attempts:
    • Increment attempt counter
    • Execute the operation
    • If successful, return immediately
    • If failed, apply backoff delay and continue
  3. Exhausted: After all attempts fail, raise exception or return error

Backoff Strategy

Use exponential backoff with the following delays:

  • Attempt 1: Immediate (0s)
  • Attempt 2: 1 second
  • Attempt 3: 2 seconds
  • Attempt 4: 4 seconds
  • Attempt 5: 8 seconds

Total delay between attempts increases exponentially to avoid overwhelming the target system.

Error Handling

  • Success: Return immediately on first success
  • Transient failure: Retry with backoff
  • Persistent failure: After 5 attempts, stop and report error with full context

Usage Examples

Network Request Example

def fetch_with_retry(url):
    """Fetch URL with retry logic"""
    for attempt in range(6):  # Initial + 5 retries
        attempt_count += 1
        try:
            response = requests.get(url, timeout=10)
            if response.status_code < 400:
                return response.json()
        except Exception as e:
            pass
        
        # Apply backoff (exponential)
        delay = min(2 ** attempt, 8)
        time.sleep(delay)
    
    raise RetryExhausted(f"Failed after {attempt_count} attempts")

File Operation Example

def write_file_with_retry(filepath, content):
    """Write file with retry logic"""
    for attempt in range(6):
        attempt_count += 1
        try:
            with open(filepath, 'w') as f:
                f.write(content)
            return True
        except Exception as e:
            pass
        
        # Apply backoff
        delay = min(2 ** attempt, 8)
        time.sleep(delay)
    
    raise RetryExhausted(f"Failed to write file after {attempt_count} attempts")

Shell Command Example

def run_command_with_retry(cmd):
    """Run shell command with retry logic"""
    for attempt in range(6):
        attempt_count += 1
        try:
            result = subprocess.run(cmd, capture_output=True, timeout=30)
            if result.returncode == 0:
                return True
        except Exception as e:
            pass
        
        # Apply backoff
        delay = min(2 ** attempt, 8)
        time.sleep(delay)
    
    raise RetryExhausted(f"Command failed after {attempt_count} attempts")

Best Practices

  1. Always track attempts: Log the number of attempts made for debugging
  2. Use meaningful delays: Exponential backoff prevents overwhelming targets
  3. Provide context on failure: When stopping, include the last error and attempt count
  4. Consider retryable errors: Only retry transient failures (network, timeout), not permanent ones (404, 500)
  5. Set appropriate timeouts: Each individual operation should have its own timeout

Common Pitfalls to Avoid

  • Infinite loops: Always ensure a maximum attempt count is enforced
  • No backoff: Linear delays can overwhelm systems; use exponential instead
  • Ignoring error types: Not all errors are retryable (e.g., 404 vs. connection error)
  • Missing context: Don't forget to log what failed and how many times

Testing the Skill

Test the skill with:

  1. Transient failures: Simulate network issues that resolve after retries
  2. Persistent failures: Ensure it stops after 5 attempts
  3. Success on first try: Verify it returns immediately without retrying
  4. Edge cases: Test at exactly 5th attempt, varying delays