anthropics / anthropics/claude-code-action

retryWithBackoff: non-retryable intent in github-file-ops-server.ts is unenforced

Open
#1,156 0 comments 0 reactions 0 assignees View on GitHub
bug mcp p2 performance
Dominant language
TypeScript
Stars
8.9k
Forks
2.1k
Avg merge
3d 9h
Merged PRs (30d)
10

Description

## Summary

`github-file-ops-server.ts` contains two `retryWithBackoff` call sites (around lines 373 and 588, both in `updateRef`) with comments that say:

```
// For non-403 errors, fail immediately without retry
console.error("Non-retryable error:", updateRefResponse.status);
throw error;
```

However, throwing from inside the operation lambda does **not** prevent `retryWithBackoff` from retrying — the function catches all errors unconditionally. So the "fail immediately" intent is silently ignored and the error is retried up to 3 times (with 5–20s backoff) regardless.

## Impact

- 400 Bad Request, 404 Not Found, 422 Unprocessable Entity on git ref updates are retried despite being deterministic failures
- Each deterministic failure wastes ~35 seconds of wall time before the action reports an error
- The misleading comments create a false impression that retry behavior is already controlled at these call sites

## Relation to #1081

This is related to #1081 (which addresses `WorkflowValidationSkipError` retries in `token.ts`). Once #1081's fix lands, the `NonRetryable` marker interface (`src/utils/errors.ts`) will be available to classify errors at these call sites too.

## Suggested fix

After #1081 is resolved, create an `HttpError` class that implements `NonRetryable` for non-retryable 4xx status codes (400, 401, 403, 404, 422), then throw `HttpError` from the two `updateRef` call sites instead of a plain `Error`. The `retryWithBackoff` default will automatically skip retries for any `NonRetryable` error.

Alternatively, pass an explicit `shouldRetry` option at these call sites that checks the HTTP status.

## Files

- `src/mcp/github-file-ops-server.ts` — two `updateRef` call sites

Contributor guide

Open the contributing guide

Research direction

Start with the two updateRef retryWithBackoff call sites in src/mcp/github-file-ops-server.ts, then read the retry behavior and the NonRetryable marker in src/utils/errors.ts. Review the dependency on #1081 and choose one of the stated approaches; done means deterministic 4xx ref-update failures return immediately while retryable errors retain their retries.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
api, backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.