Skip to content

[P1][Reliability] Add exponential backoff to Linear API calls #14

@aWN4Y25pa2EK

Description

@aWN4Y25pa2EK

Summary

Linear API calls return null on ANY error (404, 500, network timeout, auth failure) with no retry logic or error distinction.

Source

Adversarial Security Assessment

Location

  • impl/mvp/src/tools/linear-client.ts:303-306
  • impl/mvp/src/holons/root.ts:1504-1506

Current Behavior

// fetchIssue() returns null on any error
const parentIssue = await linearClient.fetchIssue(linearRef.issue_id);
if (!parentIssue) {
  throw new Error(`Parent issue not found: ${linearRef.issue_id}`);
}

Problems

  • No distinction between "not found" vs "service down"
  • Transient failures (500, timeout) treated same as permanent (404)
  • No retry for recoverable errors
  • Users don't know if Linear is down

Impact

  • Tasks fail silently on transient Linear outages
  • No self-healing for network blips
  • Poor observability

Severity

High | Likelihood: High (Linear is external service)

Recommended Fix

async function fetchWithRetry<T>(
  operation: () => Promise<T>,
  options: { maxRetries: number; baseDelayMs: number }
): Promise<T> {
  for (let attempt = 0; attempt <= options.maxRetries; attempt++) {
    try {
      return await operation();
    } catch (error) {
      if (!isTransientError(error) || attempt === options.maxRetries) {
        throw error;
      }
      const delay = options.baseDelayMs * Math.pow(2, attempt) * (0.5 + Math.random());
      await sleep(delay);
    }
  }
  throw new Error('Unreachable');
}

function isTransientError(error: unknown): boolean {
  if (error instanceof HttpError) {
    return error.status >= 500 || error.status === 429;
  }
  return error instanceof NetworkError;
}

Generated by HCA Architecture Assessment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions