
triage-ci-flake
Use when CI tests fail on main branch after PR merge, when investigating flaky test failures, or when user provides a PR URL/number to aggregate all failing tests
- Installs
- 304
- Last 24h
- —
- Trending rank
- —
- Security
- Not audited
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/payloadcms/payload --skill triage-ci-flake- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads triage-ci-flake automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
SKILL.md
The instructions your agent reads when the skill is triggered.
Triage CI Failure
Overview
Systematic workflow designed specifically for triaging and fixing end-to-end (e2e) test failures in CI, especially flaky Playwright tests that pass locally but fail in CI. E2E tests that made it to main are usually flaky due to timing, bundling, or environment differences.
CRITICAL RULE: You MUST run the reproduction workflow before proposing any fixes. No exceptions.
When to Use
- CI test fails on
mainbranch after PR was merged - Test passes locally but fails in CI
- Test failure labeled as "flaky" or intermittent
- E2E test timing out in CI only
- User provides a PR URL/number with failing checks
PR-Based Workflow (When PR URL/Number Provided)
When the user provides a PR URL (e.g., https://github.com/payloadcms/payload/pull/16701) or PR number:
Step 1: Fetch PR Status Checks
First, use tool_search with query "github pull request status checks" to load the GitHub tools.
Then use the github-pull-request_pullRequestStatusChecks tool to get all failing checks:
Tool: github-pull-request_pullRequestStatusChecks
Parameters:
pullRequestNumber: <extracted from URL or provided>
repo: { owner: "payloadcms", name: "payload" }
Step 2: Aggregate Failing Tests
Parse the status checks response and create a summary table:
| Suite | Check Status | Target URL |
|---|---|---|
| admine2elist-view | failed | [link] |
| plugin-import-export | failed | [link] |
For each failing check, the context field contains the test suite name (e.g., admin__e2e__list-view).
Step 3: Extract Failure Details from Each Check
For each failing check:
- Visit the
targetUrlto get detailed failure logs - Extract the specific test name and error message
- Add to the aggregated failure list
Present a consolidated summary:
## Failing Tests Summary
### 1. admin**e2e**list-view (3/4)
- **Test**: "should use custom pagination limit"
- **Error**: Locator `.per-page__button` not found
- **File**: test/admin/e2e/list-view/e2e.spec.ts:1495
### 2. plugin-import-export
- **Test**: "should inherit limit from list view URL"
- **Error**: Locator `.per-page__button` not found
- **File**: test/plugin-import-export/e2e.spec.ts:150
Step 4: Identify Common Patterns
Look for patterns across failures:
- Same selector errors → likely a component change needing test updates
- Same test file → localized issue
- Different errors in same suite → may be test pollution
Step 5: Proceed with Triage
For each unique failure, follow the standard reproduction workflow below.
MANDATORY First Steps
YOU MUST EXECUTE THESE COMMANDS. Reading code or analyzing logs does NOT count as reproduction.
- Extract suite name, test name, and error from CI logs
- EXECUTE: Kill port 3000 to avoid conflicts
- EXECUTE:
pnpm dev $SUITE_NAME(use run_in_background=true) - EXECUTE: Wait for server to be ready (check with curl or sleep)
- EXECUTE: Run the specific failing test with Playwright directly (npx playwright test test/TEST_SUITE_NAME/e2e.spec.ts:31:3 --headed -g "TEST_DESCRIPTION_TARGET_GOES_HERE")
- If test passes, EXECUTE:
pnpm prepare-run-test-against-prod - EXECUTE:
pnpm dev:prod $SUITE_NAMEand run test again
Only after EXECUTING these commands and seeing their output can you proceed to analysis and fixes.
"Analysis from logs" is NOT reproduction. You must RUN the commands.
Core Workflow
digraph triage_ci {
"CI failure reported" [shape=box];
"Extract details from CI logs" [shape=box];
"Identify suite and test name" [shape=box];
"Run dev server: pnpm dev $SUITE" [shape=box];
"Run specific test by name" [shape=box];
"Did test fail?" [shape=diamond];
"Debug with dev code" [shape=box];
"Run prepare-run-test-against-prod" [shape=box];
"Run: pnpm dev:prod $SUITE" [shape=box];
"Run specific test again" [shape=box];
"Did test fail now?" [shape=diamond];
"Debug bundling issue" [shape=box];
"Unable to reproduce - check logs" [shape=box];
"Fix and verify" [shape=box];
"CI failure reported" -> "Extract details from CI logs";
"Extract details from CI logs" -> "Identify suite and test name";
"Identify suite and test name" -> "Run dev server: pnpm dev $SUITE";
"Run dev server: pnpm dev $SUITE" -> "Run specific test by name";
"Run specific test by name" -> "Did test fail?";
"Did test fail?" -> "Debug with dev code" [label="yes"];
"Did test fail?" -> "Run prepare-run-test-against-prod" [label="no"];
"Run prepare-run-test-against-prod" -> "Run: pnpm dev:prod $SUITE";
"Run: pnpm dev:prod $SUITE" -> "Run specific test again";
"Run specific test again" -> "Did test fail now?";
"Did test fail now?" -> "Debug bundling issue" [label="yes"];
"Did test fail now?" -> "Unable to reproduce - check logs" [label="no"];
"Debug with dev code" -> "Fix and verify";
"Debug bundling issue" -> "Fix and verify";
}
Step-by-Step Process
1. Extract CI Details
From CI logs or GitHub Actions URL, identify:
- Suite name: Directory name (e.g.,
i18n,fields,lexical) - Test file: Full path (e.g.,
test/i18n/e2e.spec.ts) - Test name: Exact test description
- Error message: Full stack trace
- Test type: E2E (Playwright)
2. Reproduce with Dev Code
CRITICAL: Always run the specific test by name, not the full suite.
SERVER MANAGEMENT RULES:
- ALWAYS kill all servers before starting a new one
- NEVER assume ports are free
- ALWAYS wait for server ready confirmation before running tests
# ========================================
# STEP 2A: STOP ALL SERVERS
# ========================================
lsof -ti:3000 | xargs kill -9 2>/dev/null || echo "Port 3000 clear"
# ========================================
# STEP 2B: START DEV SERVER
# ========================================
# Start dev server with the suite (in background with run_in_background=true)
pnpm dev $SUITE_NAME
# ========================================
# STEP 2C: WAIT FOR SERVER READY
# ========================================
# Wait for server to be ready (REQUIRED - do not skip)
until curl -s http://localhost:3000/admin > /dev/null 2>&1; do sleep 1; done && echo "Server ready"
# ========================================
# STEP 2D: RUN SPECIFIC TEST
# ========================================
# Run ONLY the specific failing test using Playwright directly
# For E2E tests (DO NOT use pnpm test:e2e as it spawns its own server):
pnpm exec playwright test test/$SUITE_NAME/e2e.spec.ts -g "exact test name"
Did the test fail?
- ✅ YES: You reproduced it! Proceed to debug with dev code.
- ❌ NO: Continue to step 3 (bundled code test).
3. Reproduce with Bundled Code
If test passed with dev code, the issue is likely in bundled/production code.
IMPORTANT: You MUST stop the dev server before starting prod server.
# ========================================
# STEP 3A: STOP ALL SERVERS (INCLUDING DEV SERVER FROM STEP 2)
# ========================================
lsof -ti:3000 | xargs kill -9 2>/dev/null || echo "Port 3000 clear"
# ========================================
# STEP 3B: BUILD AND PACK FOR PROD
# ========================================
# Build all packages and pack them (this takes time - be patient)
pnpm prepare-run-test-against-prod
# ========================================
# STEP 3C: START PROD SERVER
# ========================================
# Start prod dev server (in background with run_in_background=true)
pnpm dev:prod $SUITE_NAME
# ========================================
# STEP 3D: WAIT FOR SERVER READY
# ========================================
# Wait for server to be ready (REQUIRED - do not skip)
until curl -s http://localhost:3000/admin > /dev/null 2>&1; do sleep 1; done && echo "Server ready"
# ========================================
# STEP 3E: RUN SPECIFIC TEST
# ========================================
# Run the specific test again using Playwright directly
pnpm exec playwright test test/$SUITE_NAME/e2e.spec.ts -g "exact test name"
Did the test fail now?
- ✅ YES: Bundling or production build issue. Look for:
- Missing exports in package.json
- Build configuration problems
- Code that behaves differently when bundled
- ❌ NO: Unable to reproduce locally. Proceed to step 4.
4. Unable to Reproduce
If you cannot reproduce locally after both attempts:
- Review CI logs more carefully for environment differences
- Check for race conditions (run test multiple times:
for i in {1..10}; do pnpm test:e2e...; done) - Look for CI-specific constraints (memory, CPU, timing)
- Consider if it's a true race condition that's highly timing-dependent
Common Flaky Test Patterns
Race Conditions
- Page navigating while assertions run
- Network requests not settled before assertions
- State updates not completed
Fix patterns:
- Use Playwright's web-first assertions (
toBeVisible(),toHaveText()) - Wait for specific conditions, not arbitrary timeouts
- Use
waitForFunction()with condition checks
Test Pollution
- Tests leaving data in database
- Shared state between tests
- Missing cleanup in
afterEach
Fix patterns:
- Track created IDs and clean up in
afterEach - Use isolated test data
- Don't use
deleteAllthat affects other tests
Timing Issues
setTimeout/sleepinstead of condition-based waiting- Not waiting for page stability
- Animations/transitions not complete
Fix patterns:
- Use
waitForPageStability()helper - Wait for specific DOM states
- Use Playwright's built-in waiting mechanisms
Linting Considerations
When fixing e2e tests, be aware of these eslint rules:
playwright/no-networkidle- AvoidwaitForLoadState('networkidle')(use condition-based waiting instead)payload/no-wait-function- Avoid customwait()functions (use Playwright's built-in waits)payload/no-flaky-assertions- Avoid non-retryable assertionsplaywright/prefer-web-first-assertions- Use built-in Playwright assertions
Existing code may violate these rules - when adding new code, follow the rules even if existing code doesn't.
Verification
After fixing:
# Ensure dev server is running on port 3000
# Run test multiple times to confirm stability
for i in {1..10}; do
pnpm exec playwright test test/$SUITE_NAME/e2e.spec.ts -g "exact test name" || break
done
# Run full suite
pnpm exec playwright test test/$SUITE_NAME/e2e.spec.ts
# If you modified bundled code, test with prod build
lsof -ti:3000 | xargs kill -9 2>/dev/null
pnpm prepare-run-test-against-prod
pnpm dev:prod $SUITE_NAME
until curl -s http://localhost:3000/admin > /dev/null; do sleep 1; done
pnpm exec playwright test test/$SUITE_NAME/e2e.spec.ts
The Iron Law
NO FIX WITHOUT REPRODUCTION FIRST
If you propose a fix before completing steps 1-3 of the workflow, you've violated this skill.
This applies even when:
- The fix seems obvious from the logs
- You've seen this error before
- Time pressure from the team
- You're confident about the root cause
- The logs show clear stack traces
No exceptions. Run the reproduction workflow first.
Rationalization Table
Every excuse for skipping reproduction, and why it's wrong:
| Rationalization | Reality |
|---|---|
| "The logs show the exact error" | Logs show symptoms, not root cause. Reproduce. |
| "I can see the problem in the code" | You're guessing. Reproduce to confirm. |
| "This is obviously a race condition" | Maybe. Reproduce to be sure. |
| "I've seen this error before" | This might be different. Reproduce. |
| "The stack trace is clear" | Stack trace shows where, not why. Reproduce. |
| "Time pressure - need to fix fast" | Reproducing IS fast. Guessing wastes time. |
| "The test file shows the issue" | Reading ≠ running. Execute the commands. |
| "I'll analyze the code first" | Code analysis comes AFTER reproduction. |
| "Let me investigate the root cause" | Reproduction IS the investigation. |
| "I need to understand the error" | Understanding comes from seeing it fail. |
Red Flags - STOP
These thoughts mean you're about to violate the skill:
- "Let me just fix the obvious issue" → STOP. Execute reproduction first.
- "I'll increase the timeout" → STOP. Find root cause via reproduction.
- "This looks like X from the logs" → STOP. Run the test.
- "I'll run the full suite" → STOP. Run specific test first.
- "Let me check the code" → STOP. Run reproduction first.
- "I can see the problem in the stack trace" → STOP. Reproduce to confirm.
- "The logs are clear enough" → STOP. Execute the commands.
- "Let me analyze..." → STOP. Analysis comes after reproduction.
All of these mean: Stop immediately. Execute the reproduction commands. No analysis without execution.
Example Session
CORRECT approach - executes commands first:
User: CI failed on i18n suite - https://github.com/.../actions/runs/XXX
Agent:
1. Extracted details from CI logs:
- Suite: i18n
- Test: "ensure translations update correctly when switching language"
- File: test/i18n/e2e.spec.ts:124
- Error: "Error loading language: en" TypeError: network error
2. Executing reproduction workflow:
[Uses Bash tool to kill ports]
$ lsof -ti:3000 | xargs kill -9 2>/dev/null || echo "Port 3000 clear"
[Uses Bash tool with run_in_background=true]
$ pnpm dev i18n
[Waits for server to start with curl check]
$ until curl -s http://localhost:3000/admin > /dev/null; do sleep 1; done && echo "Server ready"
[Uses Bash tool to run Playwright directly]
$ pnpm exec playwright test test/i18n/e2e.spec.ts -g "ensure translations update correctly when switching language"
Output shows: Test PASSED locally
3. Test passed with dev code, trying bundled code:
[Kills ports again]
$ lsof -ti:3000 | xargs kill -9 2>/dev/null
[Uses Bash tool]
$ pnpm prepare-run-test-against-prod
[Uses Bash tool with run_in_background=true]
$ pnpm dev:prod i18n
[Waits for server]
$ until curl -s http://localhost:3000/admin > /dev/null; do sleep 1; done
[Uses Bash tool]
$ pnpm exec playwright test test/i18n/e2e.spec.ts -g "ensure translations update correctly when switching language"
Output shows: Test FAILED - reproduced!
4. Now that I've reproduced it, analyzing the failure...
[Code analysis, root cause identification]
5. Implementing fix: [specific changes]
6. Verification:
[Uses Bash tool]
$ for i in {1..10}; do pnpm test:e2e i18n -g "exact test"; done
All 10 runs passed!
INCORRECT approach - analyzes without executing:
User: CI failed on i18n suite
Agent: Looking at the error logs, I can see this is a race condition...
[Analyzes code, proposes fix without running any commands]
❌ WRONG - This violates the skill. Must execute reproduction commands first.
Common Mistakes
| Mistake | Fix |
|---|---|
| Running full test suite first | Run specific test by name |
| Skipping dev code reproduction | Always try dev code first |
| Not testing with bundled code | If dev passes, test with prepare-run-test-against-prod |
| Proposing fix without reproducing | Follow the workflow - reproduce first |
Using networkidle in new code | Use condition-based waiting with waitForFunction() |
Adding arbitrary wait() calls | Use Playwright's built-in assertions and waits |
Key Principles
- Reproduce before fixing: Never propose a fix without reproducing the issue
- Test specifically: Run the exact failing test, not the full suite
- Dev first, prod second: Check dev code before bundled code
- Follow the workflow: No shortcuts - the steps exist to save time
- Verify stability: Run tests multiple times to confirm fix
Completion: Creating a PR
After you have:
- ✅ Reproduced the issue
- ✅ Implemented a fix
- ✅ Verified the fix passes locally (multiple runs)
- ✅ Tested with prod build (if applicable)
You MUST prompt the user to create a PR:
The fix has been verified and is ready for review. Would you like me to create a PR with these changes?
Summary of changes:
- [List files modified]
- [Brief description of the fix]
- [Verification results]
IMPORTANT:
- DO NOT automatically create a PR - always ask the user first
- Provide a clear summary of what was changed and why
- Include verification results (number of test runs, pass rate)
- Let the user decide whether to create the PR immediately or make additional changes first
This ensures the user has visibility and control over what gets submitted for review.
FAQ
What does the triage-ci-flake skill do?
Use when CI tests fail on main branch after PR merge, when investigating flaky test failures, or when user provides a PR URL/number to aggregate all failing tests
How do I install triage-ci-flake?
Run npx skills add https://github.com/payloadcms/payload --skill triage-ci-flake in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/triage-ci-flake/ (personal) or .claude/skills/triage-ci-flake/ (project).
Which AI agents can use triage-ci-flake?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is triage-ci-flake safe to install?
No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.
Who maintains triage-ci-flake?
It is published by payloadcms in payloadcms/payload. It has 304 recorded installs.
More from payloadcms/payload
payload
payloadcms/payload
Use when working with Payload projects (payload.config.ts, collections, fields, hooks, access control, Payload API). Use when debugging validation errors, security issues, relationship queries, transactions, or hook behavior.
generate-translations
payloadcms/payload
Use when new translation keys are added to packages to generate new translations strings
audit-dependencies
payloadcms/payload
Use when fixing dependency vulnerabilities, running pnpm audit, or when the audit-dependencies CI check fails
ui4-review
payloadcms/payload
Review UI4 CSS migrations for proper token usage. Checks that CSS variables are used instead of hardcoded values.
ui4-convert-tests
payloadcms/payload
Use when UI changes are complete and e2e tests need updating. Analyzes what changed in UI components and systematically finds/fixes affected tests.
Popular devops & cloud skills
microsoft-foundry
microsoft/azure-skills
Build, deploy, evaluate, optimize, fine-tune, and manage Microsoft Foundry agents, models, and resources end to end. USE FOR: foundry, azd ai agent, azd provision/deploy, hosted agent scaffold/develop/run/deploy/troubleshoot, prompt agent create, managed harness agent create, GitHub Copilot harness agent, create agent, update agent, add tool to agent, invoke agent, agent insights, evaluate agent, batch eval, continuous eval, continuous monitoring, agent CI/CD, optimize prompt, improve prompt, optimize agent instructions, Agent Optimizer scaffold, dataset curation from traces, deploy model, model fine-tuning (SFT/DPO/RFT), Foundry project, RBAC, role assignment, permissions, quota, capacity, region, deployment failure, AI Services, create Foundry resource, knowledge index, customize deployment, onboard, availability, training-data, grader, distillation, large file upload. DO NOT USE FOR: Azure Functions, App Service, general Azure deploy (use azure-deploy), general Azure prep (use azure
azure-diagnostics
microsoft/azure-skills
Debug Azure production issues on Azure using AppLens, Azure Monitor, resource health, and safe triage. WHEN: debug production issues, troubleshoot app service, app service high CPU, app service deployment failure, troubleshoot container apps, container app 503 or target port mismatch, troubleshoot functions, function telemetry missing or stopped after a config/connection-string change, troubleshoot AKS, VM RDP, Linux SSH, VM black screen, can't connect to VM, reset VM password, NSG or firewall blocking, kubectl cannot connect, kube-system/CoreDNS failures, pod pending, crashloop, node not ready, upgrade failures, analyze logs, KQL, insights, image pull failures, cold start issues, health probe failures, resource health, root cause of errors, troubleshoot event hubs, troubleshoot service bus, messaging SDK error, AMQP connection failure, message lock lost, lock renewal during long-running processing, service bus dead letter.
azure-prepare
microsoft/azure-skills
Prepare azd-based Azure projects for deployment: generates azure.yaml, infrastructure (Bicep/Terraform), and Dockerfiles for the Azure Developer CLI (azd) workflow. USE ONLY when the user explicitly wants to use azd as the deployment tool, or the project already has an azure.yaml file. DO NOT USE FOR: non-azd deployments, Python App Service code-only deploys (use python-appservice-deploy), or cross-cloud migration (use azure-cloud-migrate). WHEN: prepare app for azd, create azure.yaml, set up azd infrastructure, modernize app for Azure with azd, deploy with azd, function app, timer trigger, service bus trigger, event-driven function, managed identity, generate Bicep, generate Terraform, create and deploy to Azure.
azure-ai
microsoft/azure-skills
Use for Azure AI: Search, Speech, OpenAI, Document Intelligence. Helps with search, vector/hybrid search, speech-to-text, text-to-speech, transcription, OCR. WHEN: AI Search, query search, vector search, hybrid search, semantic search, speech-to-text, text-to-speech, transcribe, OCR, convert text to speech.
azure-deploy
microsoft/azure-skills
Execute Azure deployments for ALREADY-PREPARED applications that have existing .azure/deployment-plan.md and infrastructure files. DO NOT use this skill when the user asks to CREATE a new application — use azure-prepare instead. This skill runs azd up, azd deploy, terraform apply, and az deployment commands with built-in error recovery. Requires .azure/deployment-plan.md from azure-prepare and validated status from azure-validate. WHEN: "run azd up", "run azd deploy", "execute deployment", "push to production", "push to cloud", "go live", "ship it", "bicep deploy", "terraform apply", "publish to Azure", "launch on Azure". DO NOT USE WHEN: "create and deploy", "build and deploy", "create a new app", "set up infrastructure", "create and deploy to Azure using Terraform" — use azure-prepare for these.
azure-validate
microsoft/azure-skills
Pre-deployment validation for Azure readiness. Run deep checks on configuration, infrastructure (Bicep or Terraform), RBAC role assignments, managed identity permissions, and prerequisites before deploying. WHEN: validate my app, check deployment readiness, run preflight checks, verify configuration, check if ready to deploy, validate azure.yaml, validate Bicep, test before deploying, troubleshoot deployment errors, validate Azure Functions, validate function app, validate serverless deployment, verify RBAC roles, check role assignments, review managed identity permissions, what-if analysis, validate Container Apps deployment.