Troubleshooting¶
Debugging Flowchart¶
flowchart TD
A[Deployment Issue] --> B{Workflow triggered?}
B -->|No| C[Check on: issue_comment trigger]
B -->|Yes| D{branch-deploy responded?}
D -->|No| E[Check permissions & triggers]
D -->|Yes| F{Terraform ran?}
F -->|No| G[Check mode: execute]
F -->|Yes| H{Plan/Apply succeeded?}
H -->|No| I[Check Terraform error]
H -->|Yes| J[Check PR comment output]
Common Issues¶
"No plan file found for this SHA"¶
Cause: You tried to .apply without running .plan first, or new commits changed the SHA.
Fix:
- Run
.plan to <env>first - If you made new commits after planning, run
.planagain - The plan is tied to a specific commit SHA for safety
❌ .apply to dev
→ Error: No plan file found for SHA abc123
✅ .plan to dev
→ Plan saved for SHA abc123
✅ .apply to dev
→ Applies the saved plan
"Environment not found"¶
Cause: The environment in your command doesn't exist in .tf-branch-deploy.yml.
Fix:
- Check your config file for typos
- Environment names are case-sensitive
- Ensure the
environmentssection includes your target
environments:
dev: # ✅ .plan to dev
working-directory: terraform/dev
Dev: # ✅ .plan to Dev (different!)
working-directory: terraform/Dev
"Config file not found"¶
Cause: .tf-branch-deploy.yml doesn't exist in the repository root.
Fix:
- Create the config file in your repository root
- Or specify a custom path:
- uses: scarowar/terraform-branch-deploy@v0.2.0
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
config-path: terraform/.tf-branch-deploy.yml
"Branch is outdated"¶
Cause: Your PR branch is behind the target branch (main).
Fix:
The fix depends on your update-branch and outdated-mode settings:
You'll see a warning but deployment proceeds. Consider updating your branch:
The action will auto-update your branch. This may re-trigger CI.
Deployment is blocked until you update:
- Click "Update branch" in the GitHub PR UI
- Or merge main into your branch manually
"Environment locked by another PR"¶
Cause: Another user has locked the environment.
Fix:
- Check who has the lock:
.wcid - Ask them to unlock or wait for their deployment
- If lock is stuck, unlock from any PR:
.unlock <env>
Sticky Locks
If sticky-locks: true, locks persist after deployment. The deployer must manually .unlock.
"Deployment order violation"¶
Cause: You have enforced-deployment-order set and tried to skip an environment.
Fix:
If your config has:
You must deploy to dev, then staging, before prod:
❌ .apply to prod
→ Error: Must deploy to staging before prod
✅ .apply to dev
✅ .apply to staging
✅ .apply to prod
Plan Output Not Appearing in PR¶
Cause: tfcmt issue or GitHub token permissions.
Fix:
- Ensure your token has
pull-requests: write:
- Check the workflow logs for tfcmt errors
- The action installs tfcmt automatically—no setup needed
"Permission denied" Errors¶
Cause: GitHub token missing required permissions.
Fix:
Add all required permissions to your workflow:
permissions:
contents: write # For checkout and branch operations
pull-requests: write # For PR comments
deployments: write # For deployment status
checks: read # If using checks validation
statuses: read # If using required contexts
Environment Lock Stuck¶
Cause: Previous deployment failed without releasing lock.
Fix:
Comment .unlock <env> on any open PR:
Global Lock
If someone used .lock --global, you need .unlock --global to release all environments.
"Admin bypass not working"¶
Cause: Admin team lookup failing.
Fix:
If using GitHub teams in admins:
- Ensure
admins-patis set with a PAT that hasread:orgscope - Team format is
org-name/team-slug(not display name) - The PAT owner must be able to view team membership
# Correct
admins: "my-org/platform-team"
admins-pat: ${{ secrets.ADMIN_PAT }}
# Wrong - missing PAT
admins: "my-org/platform-team"
# Wrong - display name instead of slug
admins: "my-org/Platform Team"
Cache/Artifact Not Found¶
Cause: Plan cache expired or different SHA.
Fix:
- GitHub Actions cache expires after 7 days of no access
- New commits = new SHA = new cache key
- Run
.planagain to regenerate
Debug Mode¶
Enable verbose logging:
This shows:
- Full terraform command output
- branch-deploy internal state
- Cache operations
Dry Run Mode¶
Test without executing terraform:
- uses: scarowar/terraform-branch-deploy@v0.2.0
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
dry-run: true
This prints commands that would run without executing them.
Getting Help¶
When reporting issues, include:
- Workflow file (sanitized)
.tf-branch-deploy.ymlconfig- Error message from logs
- PR comment that triggered the issue