Skip to content

Commit 5523a5a

Browse files
feat: skip Claude step gracefully when Anthropic API is unavailable
## Summary - Add pre-flight API availability check before running `claude-code-action` - Skip the Claude step gracefully (warning, not failure) when the API returns 5xx or is unreachable - Belt-and-suspenders: `continue-on-error: true` + post-execution re-check distinguishes service outages from legitimate errors ## Problem When the Anthropic API is down, the Claude step fails with a hard error, blocking the entire CI pipeline. Example: [dotCMS/core run 24461196854](https://github.com/dotCMS/core/actions/runs/24461196854) ``` API Error: 500 {"type":"error","error":{"type":"api_error","message":"Internal server error"}} · check status.claude.com ``` ## Solution Two layers of protection in `claude-executor.yml`: **Layer 1 — Pre-flight check** (catches most outages): - `curl` the `/v1/models` endpoint with a 15s timeout before running Claude - 5xx / network failures → `available=false` → skip Claude step → warn and succeed - Auth errors (401/403), rate limits (429) → `available=true` → proceed so action can surface the specific error **Layer 2 — Runtime protection** (catches mid-execution degradation): - `continue-on-error: true` on the Claude step - Post-execution step checks if Claude failed - If failed AND API is now returning 500 → skip gracefully (service issue) - If failed AND API is now returning 200 → re-fail with "legitimate error" message ## Test Validated in `dotCMS/core-workflow-test#460`: - Pre-flight check correctly passes when API is available - `Handle Claude execution result` correctly re-fails for non-service errors (workflow validation failure in test PR) - The skip path is code-correct (would activate when API returns 5xx) ## Consumer repos to update after merge - `dotCMS/core` — update `@v2.0.0` → new tag - `dotCMS/core-workflow-test` — update `@v2.0.0` → new tag Fixes: dotCMS/core#35328 Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent ac1713b commit 5523a5a

1 file changed

Lines changed: 71 additions & 0 deletions

File tree

.github/workflows/claude-executor.yml

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
# - Configures the anthropics/claude-code-action with configurable claude_args
1414
# - Handles the actual Claude AI interaction
1515
# - Provides a single source of truth for Claude execution configuration
16+
# - Gracefully skips when the Claude API is unavailable (5xx / network errors)
1617
#
1718
# USAGE: Called by orchestrator workflows with different parameters
1819
# for interactive vs automatic modes and different tool configurations.
@@ -66,12 +67,82 @@ jobs:
6667
with:
6768
fetch-depth: 1
6869

70+
# Pre-flight check: verify the Claude API is reachable before attempting execution.
71+
# Treats 5xx responses and network failures as "unavailable" and skips gracefully.
72+
# Auth errors (401/403) and rate limits (429) still proceed so the action can surface them.
73+
- name: Check Claude API availability
74+
id: api-check
75+
run: |
76+
echo "Checking Claude API availability..."
77+
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
78+
--max-time 15 \
79+
--retry 2 \
80+
--retry-delay 3 \
81+
-H "x-api-key: ${{ secrets.ANTHROPIC_API_KEY }}" \
82+
-H "anthropic-version: 2023-06-01" \
83+
"https://api.anthropic.com/v1/models" 2>/dev/null) || HTTP_CODE="000"
84+
85+
echo "API response code: $HTTP_CODE"
86+
87+
case "$HTTP_CODE" in
88+
200)
89+
echo "available=true" >> "$GITHUB_OUTPUT"
90+
echo "✅ Claude API is available"
91+
;;
92+
500|503|529|000)
93+
echo "available=false" >> "$GITHUB_OUTPUT"
94+
echo "::warning::Claude AI service is unavailable (HTTP $HTTP_CODE). Skipping Claude Code step. Check https://status.anthropic.com"
95+
;;
96+
*)
97+
# For auth errors (401/403), rate limits (429), or unexpected codes:
98+
# proceed and let the action report the specific error.
99+
echo "available=true" >> "$GITHUB_OUTPUT"
100+
echo "HTTP $HTTP_CODE received — proceeding with Claude execution"
101+
;;
102+
esac
103+
69104
- name: Run Claude Code
70105
id: claude
106+
if: steps.api-check.outputs.available == 'true'
107+
continue-on-error: true
71108
uses: anthropics/claude-code-action@v1
72109
with:
73110
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
74111
prompt: ${{ inputs.prompt }}
75112
claude_args: ${{ inputs.claude_args }}
76113
use_sticky_comment: "true"
77114
track_progress: "true"
115+
116+
# If the Claude step failed at runtime, re-check the API to determine whether
117+
# the failure was caused by service degradation (skip gracefully) or a real error
118+
# (fail the job so the team is alerted).
119+
- name: Handle Claude execution result
120+
if: steps.api-check.outputs.available == 'true' && steps.claude.outcome == 'failure'
121+
run: |
122+
echo "Claude Code step failed. Checking if this is due to service unavailability..."
123+
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
124+
--max-time 10 \
125+
-H "x-api-key: ${{ secrets.ANTHROPIC_API_KEY }}" \
126+
-H "anthropic-version: 2023-06-01" \
127+
"https://api.anthropic.com/v1/models" 2>/dev/null) || HTTP_CODE="000"
128+
129+
echo "Post-execution API check: HTTP $HTTP_CODE"
130+
131+
case "$HTTP_CODE" in
132+
200)
133+
echo "::error::Claude Code step failed and the API is currently reachable — this appears to be a legitimate error. Review the logs above."
134+
exit 1
135+
;;
136+
*)
137+
echo "::warning::Claude Code step failed due to API service degradation (HTTP $HTTP_CODE). Skipping gracefully."
138+
echo "For current service status, visit: https://status.anthropic.com"
139+
;;
140+
esac
141+
142+
- name: Claude service unavailable — step skipped
143+
if: steps.api-check.outputs.available != 'true'
144+
run: |
145+
echo "::warning::Claude AI Orchestrator was skipped because the Claude API is currently unavailable."
146+
echo "The pipeline continues normally. Claude review will run on the next PR push when the service is restored."
147+
echo ""
148+
echo "For current service status, visit: https://status.anthropic.com"

0 commit comments

Comments
 (0)