Compare commits

..

1 Commits

Author SHA1 Message Date
Ashwin Bhat
6147037db9 feat: add detailed debugging info for intermittent 403 errors on ref updates
Enhanced error messages when GitHub API returns "Resource not accessible by integration"
errors during git reference updates. The improved error output includes:
- Repository and branch context
- Token metadata (length and prefix)
- Parent and target SHA details
- GitHub Actions environment info
- Full API response details
- Debugging hints for common causes

This helps diagnose whether failures are due to protected branches, permission
issues, race conditions, or transient GitHub API issues.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-19 20:52:32 -07:00
2 changed files with 106 additions and 109 deletions

View File

@@ -1,102 +0,0 @@
---
description: Analyze and fix CI failures by examining logs and making targeted fixes
allowed_tools: Edit,MultiEdit,Write,Read,Glob,Grep,LS,Bash(git:*),Bash(bun:*),Bash(npm:*),Bash(npx:*),Bash(gh:*)
---
# Fix CI Failures
You are tasked with analyzing CI failure logs and fixing the issues. Follow these steps:
## Context Provided
$ARGUMENTS
## Important Context Information
Look for these key pieces of information in the arguments:
- **Failed CI Run URL**: Link to the failed CI run
- **Failed Jobs**: List of jobs that failed
- **PR Number**: The PR number to comment on
- **Branch Name**: The fix branch you're working on
- **Base Branch**: The original PR branch
- **Error logs**: Detailed logs from failed jobs
## Step 1: Analyze the Failure
Parse the provided CI failure information to understand:
- Which jobs failed and why
- The specific error messages and stack traces
- Whether failures are test-related, build-related, or linting issues
## Step 2: Search and Understand the Codebase
Use search tools to locate the failing code:
- Search for the failing test names or functions
- Find the source files mentioned in error messages
- Review related configuration files (package.json, tsconfig.json, etc.)
## Step 3: Apply Targeted Fixes
Make minimal, focused changes:
- **For test failures**: Determine if the test or implementation needs fixing
- **For type errors**: Fix type definitions or correct the code logic
- **For linting issues**: Apply formatting using the project's tools
- **For build errors**: Resolve dependency or configuration issues
- **For missing imports**: Add the necessary imports or install packages
Requirements:
- Only fix the actual CI failures, avoid unrelated changes
- Follow existing code patterns and conventions
- Ensure changes are production-ready, not temporary hacks
- Preserve existing functionality while fixing issues
## Step 4: Commit and Push Changes
After applying ALL fixes:
1. Stage all modified files with `git add -A`
2. Commit with: `git commit -m "Fix CI failures: [describe specific fixes]"`
3. Document which CI jobs/tests were addressed
4. **CRITICAL**: Push the branch with `git push origin HEAD` - You MUST push the branch after committing
## Step 5: Create PR Comment
After successfully pushing the fixes, create a comment on the original PR to notify about the auto-fix:
1. Extract the PR number, branch name, and base branch from the context provided
2. Use gh CLI to create a comment with the fix information
3. Include a link to create a pull request from the fix branch
Use this command format (replace placeholders with actual values):
```bash
gh pr comment PR_NUMBER --body "## 🤖 CI Auto-Fix Available
Claude has analyzed the CI failures and prepared fixes.
[**→ Create pull request to fix CI**](https://github.com/OWNER/REPO/compare/BASE_BRANCH...FIX_BRANCH?quick_pull=1)
_This fix was generated automatically based on the failed CI run._"
```
## Step 6: Verify Fixes Locally
Run available verification commands:
- Execute the failing tests locally to confirm they pass
- Run the project's lint command (check package.json for scripts)
- Run type checking if available
- Execute any build commands to ensure compilation succeeds
## Important Guidelines
- Focus exclusively on fixing the reported CI failures
- Maintain code quality and follow the project's established patterns
- If a fix requires significant refactoring, document why it's necessary
- When multiple solutions exist, choose the simplest one that maintains code quality
Begin by analyzing the failure details provided above.

View File

@@ -367,6 +367,7 @@ server.tool(
// We're seeing intermittent 403 "Resource not accessible by integration" errors
// on certain repos when updating git references. These appear to be transient
// GitHub API issues that succeed on retry.
let lastErrorDetails: any = null;
await retryWithBackoff(
async () => {
const updateRefResponse = await fetch(updateRefUrl, {
@@ -385,17 +386,48 @@ server.tool(
if (!updateRefResponse.ok) {
const errorText = await updateRefResponse.text();
let errorJson: any = {};
try {
errorJson = JSON.parse(errorText);
} catch {
// If not JSON, use the text as-is
}
// Collect debugging information
const debugInfo = {
status: updateRefResponse.status,
statusText: updateRefResponse.statusText,
headers: Object.fromEntries(updateRefResponse.headers.entries()),
errorBody: errorJson || errorText,
context: {
repository: `${owner}/${repo}`,
branch: branch,
baseBranch: process.env.BASE_BRANCH,
targetSha: newCommitData.sha,
parentSha: baseSha,
isGitHubAction: !!process.env.GITHUB_ACTIONS,
eventName: process.env.GITHUB_EVENT_NAME,
isPR: process.env.IS_PR,
tokenLength: githubToken?.length || 0,
tokenPrefix: githubToken?.substring(0, 10) + "...",
apiUrl: updateRefUrl,
},
};
lastErrorDetails = debugInfo;
const error = new Error(
`Failed to update reference: ${updateRefResponse.status} - ${errorText}`,
`Failed to update reference: ${updateRefResponse.status} - ${errorText}\n\nDebug Info: ${JSON.stringify(debugInfo, null, 2)}`,
);
// Only retry on 403 errors - these are the intermittent failures we're targeting
if (updateRefResponse.status === 403) {
console.error("403 Error encountered (will retry):", debugInfo);
throw error;
}
// For non-403 errors, fail immediately without retry
console.error("Non-retryable error:", updateRefResponse.status);
console.error("Non-retryable error:", debugInfo);
throw error;
}
},
@@ -405,7 +437,23 @@ server.tool(
maxDelayMs: 5000, // Max 5 seconds delay
backoffFactor: 2, // Double the delay each time
},
);
).catch((error) => {
// If all retries failed, enhance the error message with collected details
if (lastErrorDetails) {
throw new Error(
`All retry attempts failed for ref update.\n\n` +
`Final error: ${error.message}\n\n` +
`Debugging hints:\n` +
`- Check if branch '${branch}' is protected and the GitHub App has bypass permissions\n` +
`- Verify the token has 'contents:write' permission for ${owner}/${repo}\n` +
`- Check for concurrent operations updating the same branch\n` +
`- Token appears to be: ${lastErrorDetails.context.tokenPrefix}\n` +
`- This may be a transient GitHub API issue if it works on retry\n\n` +
`Full debug details: ${JSON.stringify(lastErrorDetails, null, 2)}`,
);
}
throw error;
});
const simplifiedResult = {
commit: {
@@ -573,6 +621,7 @@ server.tool(
// We're seeing intermittent 403 "Resource not accessible by integration" errors
// on certain repos when updating git references. These appear to be transient
// GitHub API issues that succeed on retry.
let lastErrorDetails: any = null;
await retryWithBackoff(
async () => {
const updateRefResponse = await fetch(updateRefUrl, {
@@ -591,18 +640,52 @@ server.tool(
if (!updateRefResponse.ok) {
const errorText = await updateRefResponse.text();
let errorJson: any = {};
try {
errorJson = JSON.parse(errorText);
} catch {
// If not JSON, use the text as-is
}
// Collect debugging information
const debugInfo = {
status: updateRefResponse.status,
statusText: updateRefResponse.statusText,
headers: Object.fromEntries(updateRefResponse.headers.entries()),
errorBody: errorJson || errorText,
context: {
operation: "delete_files",
repository: `${owner}/${repo}`,
branch: branch,
baseBranch: process.env.BASE_BRANCH,
targetSha: newCommitData.sha,
parentSha: baseSha,
isGitHubAction: !!process.env.GITHUB_ACTIONS,
eventName: process.env.GITHUB_EVENT_NAME,
isPR: process.env.IS_PR,
tokenLength: githubToken?.length || 0,
tokenPrefix: githubToken?.substring(0, 10) + "...",
apiUrl: updateRefUrl,
},
};
lastErrorDetails = debugInfo;
const error = new Error(
`Failed to update reference: ${updateRefResponse.status} - ${errorText}`,
`Failed to update reference: ${updateRefResponse.status} - ${errorText}\n\nDebug Info: ${JSON.stringify(debugInfo, null, 2)}`,
);
// Only retry on 403 errors - these are the intermittent failures we're targeting
if (updateRefResponse.status === 403) {
console.log("Received 403 error, will retry...");
console.error(
"403 Error encountered during delete (will retry):",
debugInfo,
);
throw error;
}
// For non-403 errors, fail immediately without retry
console.error("Non-retryable error:", updateRefResponse.status);
console.error("Non-retryable error during delete:", debugInfo);
throw error;
}
},
@@ -612,7 +695,23 @@ server.tool(
maxDelayMs: 5000, // Max 5 seconds delay
backoffFactor: 2, // Double the delay each time
},
);
).catch((error) => {
// If all retries failed, enhance the error message with collected details
if (lastErrorDetails) {
throw new Error(
`All retry attempts failed for ref update during file deletion.\n\n` +
`Final error: ${error.message}\n\n` +
`Debugging hints:\n` +
`- Check if branch '${branch}' is protected and the GitHub App has bypass permissions\n` +
`- Verify the token has 'contents:write' permission for ${owner}/${repo}\n` +
`- Check for concurrent operations updating the same branch\n` +
`- Token appears to be: ${lastErrorDetails.context.tokenPrefix}\n` +
`- This may be a transient GitHub API issue if it works on retry\n\n` +
`Full debug details: ${JSON.stringify(lastErrorDetails, null, 2)}`,
);
}
throw error;
});
const simplifiedResult = {
commit: {