⚠️ Experimental. Auto-fix is opt-in and disabled by default. AI-generated code changes can be incorrect, incomplete, or even introduce new bugs. Always review the pull request carefully before merging.
When a build fails and autoFix: true is set, the plugin runs this workflow automatically:
- Sends the error logs to your configured AI provider and asks for a fix suggestion
- Validates every proposed file path (no path traversal, must match the allow-list)
- Validates every unified diff before touching any branch
- Creates a new branch (
fix/jenkins-ai-<build#>-<timestamp>) via the SCM REST API - Applies the diffs and commits all changes atomically
- Opens a pull request with a structured description (root cause, file changes, build link)
- Stores the PR URL in the Jenkins build sidebar under "AI Auto-Fix"
If any step fails (invalid diff, missing credentials, API error), the branch is deleted and the
build is marked with status FAILED — the original build result is not affected.
| Requirement | Details |
|---|---|
| Jenkins | 2.528.3 or higher |
| Java | 17+ |
| AI provider | Any supported provider configured in global settings (Anthropic Claude, AWS Bedrock, Azure OpenAI, Custom Okta, DeepSeek, Google Gemini, Microsoft Foundry, Ollama, OpenAI, Qwen) |
| SCM | GitHub.com, GitHub Enterprise, GitLab.com, GitLab self-managed, Bitbucket Cloud, or Bitbucket Server / Data Center |
| Token | Personal Access Token (PAT) with read + write access to the repository |
The plugin uses a Jenkins Secret text credential or a Username with password credential. For username/password credentials, the password field is used as the SCM token. SSH keys are not supported for auto-fix API calls.
- Go to https://github.com/settings/tokens → Generate new token (classic)
- Grant scopes:
repo(all) - Copy the token
For GitHub Enterprise, use https://<your-ghe-host>/settings/tokens.
- Go to User Settings → Access Tokens (or Project → Settings → Access Tokens for a project-scoped token)
- Grant scopes:
api(or at minimumread_repository+write_repository) - Copy the token
- Go to Personal Settings → App passwords
- Grant permissions: Repositories: Read + Write, Pull requests: Read + Write
- Copy the generated app password (format:
username:apppasswordis not what you store — store only the app password value; set your Bitbucket username separately if needed)
Bitbucket Cloud uses
username:apppasswordas the HTTP Basic Auth credential. Store only the app-password value in Jenkins; the plugin uses the repository owner from the remote URL as the username.
- Manage Jenkins → Credentials → (global) → Add Credentials
- Kind: Secret text or Username with password
- Secret/password: paste your token
- ID: choose a memorable ID (e.g.
github-autofix-pat)
pipeline {
agent any
stages {
stage('Build') {
steps {
sh 'mvn clean verify'
}
}
}
post {
failure {
explainError(
autoFix: true,
autoFixCredentialsId: 'github-autofix-pat'
)
}
}
}The plugin automatically detects the remote URL from the job's SCM configuration (the same repository the build checks out from). A PR is opened on that repository.
Pipeline jobs that use checkout scm inside a script block, or multi-branch pipelines with
complex SCM configs, may not expose the remote URL automatically. Provide it explicitly:
explainError(
autoFix: true,
autoFixCredentialsId: 'github-autofix-pat',
autoFixRemoteUrl: 'https://github.com/my-org/my-repo'
)explainError(
autoFix: true,
autoFixCredentialsId: 'ghe-pat',
autoFixScmType: 'github',
autoFixGithubEnterpriseUrl: 'https://github.mycompany.com'
)explainError(
autoFix: true,
autoFixCredentialsId: 'gitlab-pat',
autoFixScmType: 'gitlab',
autoFixGitlabUrl: 'https://gitlab.mycompany.com'
)explainError(
autoFix: true,
autoFixCredentialsId: 'bitbucket-app-password',
autoFixScmType: 'bitbucket'
)Bitbucket Server uses a completely different REST API (/rest/api/1.0) from Bitbucket Cloud.
URL auto-detection works for standard Server clone URLs; use autoFixScmType: 'bitbucketserver'
to force it for non-standard hostnames.
Create a PAT on Bitbucket Server:
- Log in → Account Settings → HTTP access tokens
- Click Create token
- Grant permissions: Repository: Write, Pull requests: Write
- Copy the generated token
HTTP access tokens require Bitbucket Server 5.5+ (Data Center 7.x+). For older instances, store credentials as
username:password— the client will use Basic Auth.
Auto-detection (SSH clone URL):
Bitbucket Server SSH clone URLs look like ssh://git@bitbucket.company.com:7999/PROJ/repo.git.
The plugin detects the port-7999 SSH scheme and configures Server API automatically.
explainError(
autoFix: true,
autoFixCredentialsId: 'bitbucket-server-pat'
// autoFixScmType not needed — auto-detected from ssh://.../:7999/... URL
)Auto-detection (HTTPS clone URL):
Bitbucket Server HTTPS clone URLs use /scm/ in the path:
https://bitbucket.company.com/scm/PROJ/repo.git.
explainError(
autoFix: true,
autoFixCredentialsId: 'bitbucket-server-pat'
// auto-detected from .../scm/... URL
)Manual override (custom hostname):
explainError(
autoFix: true,
autoFixCredentialsId: 'bitbucket-server-pat',
autoFixScmType: 'bitbucketserver',
autoFixBitbucketUrl: 'https://bitbucket.company.com'
)
autoFixBitbucketUrlis the base URL of your Bitbucket Server instance (no/rest/api/1.0suffix — the plugin appends it automatically).
After the build completes:
- Open the build page in Jenkins
- Click "AI Auto-Fix" in the left sidebar
- If a PR was created, you'll see a button linking directly to it
- If the fix was skipped or failed, the status message explains why
The PR description includes:
- Root cause summary from the AI
- List of changed files with one-line descriptions
- Build details (job name, build number, fix type, confidence level)
| Parameter | Type | Default | Description |
|---|---|---|---|
autoFix |
boolean | false |
Enable auto-fix. Must be true to activate the feature |
autoFixCredentialsId |
string | '' |
Required. Jenkins Secret text or Username with password credentials ID for the SCM token |
autoFixRemoteUrl |
string | '' |
SCM remote URL. Auto-detected from job SCM config if empty |
autoFixScmType |
string | '' |
Force SCM type: github, gitlab, bitbucket, or bitbucketserver. Required for self-hosted instances whose hostname is not github.com, gitlab.com, or bitbucket.org |
autoFixGithubEnterpriseUrl |
string | '' |
Base URL of GitHub Enterprise (e.g. https://github.mycompany.com) |
autoFixGitlabUrl |
string | '' |
Base URL of self-hosted GitLab (e.g. https://gitlab.mycompany.com) |
autoFixBitbucketUrl |
string | '' |
Base URL of Bitbucket Server (e.g. https://bitbucket.mycompany.com). Leave empty for Bitbucket Cloud |
autoFixAllowedPaths |
string | see below | Comma-separated glob patterns for files the AI may modify |
autoFixDraftPr |
boolean | false |
Open the PR as a draft (GitHub and GitLab only) |
autoFixTimeoutSeconds |
int | 120 |
Max seconds to wait for the entire auto-fix workflow |
autoFixPrTemplate |
string | '' |
Custom Markdown template for the PR body (see PR template) |
pom.xml, build.gradle, build.gradle.kts, *.properties, *.yml, *.yaml,
Jenkinsfile, Dockerfile, package.json, requirements.txt, go.mod
Files outside this list are never modified, regardless of what the AI suggests.
The default PR body looks like this:
## AI Auto-Fix for my-job #42
This pull request was automatically generated by the Explain Error Plugin
to address a build failure.
### Root Cause
<AI explanation>
### Changes
- **pom.xml** (modify): Bump jackson-databind from 2.14.0 to 2.15.2
### Build Details
- **Job:** my-folder/my-job
- **Build:** #42
- **Fix Type:** dependency
- **Confidence:** highTo customise it, pass a Markdown string with {placeholder} tokens:
explainError(
autoFix: true,
autoFixCredentialsId: 'github-autofix-pat',
autoFixPrTemplate: '''
## Auto-fix — {jobName} #{buildNumber}
**Root cause:** {explanation}
**Files changed:** {changesSummary}
_Confidence: {confidence} | Type: {fixType}_
'''
)Available placeholders: {jobName}, {buildNumber}, {explanation}, {changesSummary},
{fixType}, {confidence}.
Auto-fix works best for failures where the root cause is specific and mechanical:
| Likely to work ✅ | Unlikely to work ❌ |
|---|---|
Outdated/missing dependency version in pom.xml or build.gradle |
Failing unit tests with logic errors |
Missing or wrong property in *.properties / *.yml |
Complex refactoring required |
Wrong Java/Python/Node version in Dockerfile or CI config |
Environment-specific issues (missing secrets, network) |
Syntax error in Jenkinsfile or *.yaml |
Flaky tests |
Missing package.json dependency |
Multi-file architectural changes |
The AI sets a confidence level (high, medium, low). The plugin only proceeds when
confidence is high or medium. Even then, treat the PR as a starting point, not a
guaranteed fix.
- The token is retrieved from Jenkins Credentials at runtime and never logged
- The branch name is
fix/jenkins-ai-<build#>-<timestamp>— no user-controlled input - File paths are validated against: absolute-path check, path-traversal check (
../), and the allow-list globs — in that order — before any branch is created - The diff is parsed and validated before it is applied; malformed diffs abort the workflow
- The token has the minimum scope needed: write access to the single repository
The plugin does not auto-merge. A human must review and merge the PR.
You set autoFix: true but forgot autoFixCredentialsId. Add the credentials ID:
explainError(autoFix: true, autoFixCredentialsId: 'my-github-pat')The credentials ID you provided does not exist in Jenkins, the credential type is not Secret text or Username with password, or the build does not have permission to access it. Check Manage Jenkins → Credentials.
The plugin could not determine the remote URL from the job's SCM config. Provide it explicitly:
explainError(
autoFix: true,
autoFixCredentialsId: 'my-pat',
autoFixRemoteUrl: 'https://github.com/org/repo'
)The AI suggested modifying a file not in autoFixAllowedPaths. Either add the pattern:
autoFixAllowedPaths: 'pom.xml,build.gradle,src/main/**/*.java'Or, if the suggestion looks wrong, the AI may have misidentified the root cause — the explanation step output can help diagnose this.
The AI returned fixable: false or confidence: low. This is the expected behaviour for
failures that cannot be automatically resolved. Check the explanation for root cause details.
Increase autoFixTimeoutSeconds (default 120 s). The branch is deleted automatically on
timeout so no orphaned branches are left behind.
Draft PRs are only supported on GitHub and GitLab. Bitbucket Cloud and Bitbucket Server
do not have a native draft PR concept; the PR will be created as a regular open PR regardless of
autoFixDraftPr: true.
- Bitbucket Server multi-file commits: Unlike Bitbucket Cloud (atomic), Bitbucket Server commits each file separately in sequence. This is not atomic, but the fix runs on a dedicated branch so partial commits are harmless.
- Multi-SCM jobs: only the first configured SCM remote is used for URL extraction.
- SSH remotes: SSH URLs (
git@github.com:org/repo.git) are parsed and converted to HTTPS for API calls. The PAT must be a HTTPS token, not an SSH key. - AI diff quality: LLM-generated unified diffs are imperfect. Expect occasional failures where the diff context lines don't match the actual file. A fuzzy ±3-line matcher handles minor offsets, but large context mismatches still fail cleanly (with rollback).
- Pipeline SCM detection: works with
GitSCM(git plugin) andCpsScmFlowDefinition. Custom SCM plugins that don't exposegetRepositories()requireautoFixRemoteUrl.