Skip to content

Add retry logic with jitter for sub_issue_write to handle parallel calls #1842

@SamMorrowDrums

Description

@SamMorrowDrums

Problem

When sub_issue_write tool is called in parallel (common with AI agents), multiple calls can fail with:

422 An error occurred while adding the sub-issue to the parent issue. Priority has already been taken

This happens because GitHub's sub-issues API assigns priority sequentially, and parallel calls conflict when they try to claim the same priority slot.

Proposed Solution

Add retry logic with random jitter to sub_issue_write operations:

  1. Retry up to 3 times on 422 errors related to priority conflicts
  2. Add random jitter (e.g., 50-200ms) before each retry to desynchronize parallel calls
  3. Only retry on specific "Priority has already been taken" errors, not all 422s

Example Implementation

func (s *SubIssueService) Add(ctx context.Context, owner, repo string, issueNum int, subIssueID int64) (*github.Issue, error) {
    const maxRetries = 3
    
    for attempt := 0; attempt < maxRetries; attempt++ {
        if attempt > 0 {
            // Random jitter: 50-200ms to desynchronize parallel retries
            jitter := time.Duration(50+rand.Intn(150)) * time.Millisecond
            time.Sleep(jitter)
        }
        
        issue, resp, err := s.client.Issues.AddSubIssue(ctx, owner, repo, issueNum, subIssueID)
        if err == nil {
            return issue, nil
        }
        
        // Only retry on priority conflict errors
        if resp != nil && resp.StatusCode == 422 && strings.Contains(err.Error(), "Priority has already been taken") {
            continue
        }
        
        return nil, err
    }
    
    return nil, fmt.Errorf("failed after %d retries: priority conflict", maxRetries)
}

Why This Matters

Parallel tool calling is very popular with AI agents. When an agent needs to add multiple sub-issues to an epic, it naturally calls them in parallel for efficiency. Without retry logic, a significant portion of these calls fail, degrading the user experience.

Acceptance Criteria

  • sub_issue_write with add method retries up to 3 times on priority conflicts
  • Random jitter (50-200ms) is added between retries
  • Other 422 errors are not retried
  • Unit tests cover retry behavior
  • Existing functionality is preserved

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions