CI Troubleshoot

SkillFiles & storage

Diagnose failed GitHub Actions runs for pi-agent-dashboard: the 10-file workflow taxonomy, the release pipeline, known failure modes, and how to read `gh run` logs and retrigger jobs. Use when a CI run is red, a release is stuck, a workflow won''t dispatch, or you need to know which workflow does what. See `release-cut` to trigger a release, `release-revoke` to revoke one.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the CI Troubleshoot skill

What this skill tells your AI

The instructions your AI receives, as published by blackbelttechnology/pi-agent-dashboard in .pi/skills/ci-troubleshoot/SKILL.md and read by ahel’s review.

Diagnose CI failures for pi-agent-dashboard. The repo has 10 workflow files: 8 entry workflows and 2 reusable workflows.

flowchart LR
  ci[ci.yml] --> checks[tests + lint + build]
  deploy[deploy-site.yml] --> pages[GitHub Pages]
  native[ci-e2e-electron.yml] --> nativeTests[native Electron E2E]
  ciSmoke[ci-smoke.yml] --> smoke[_smoke.yml]
  publish[publish.yml] --> smoke
  ciElectron[ci-electron.yml] --> electron[_electron-build.yml]
  nightly[nightly.yml] --> electron
  publish --> electron
  publish --> release[GitHub Release]
  release --> sync[sync-release-version.yml]

Full per-workflow detail: references/workflow-taxonomy.md.

First moves — always run these

pnpm exec tsx .pi/skills/ci-troubleshoot/scripts/list-recent-runs.ts                  # last 10 runs across all workflows
pnpm exec tsx .pi/skills/ci-troubleshoot/scripts/list-recent-runs.ts --failed         # only failed
pnpm exec tsx .pi/skills/ci-troubleshoot/scripts/show-failed-run.ts <run-id>          # failed steps + log tails
pnpm exec tsx .pi/skills/ci-troubleshoot/scripts/show-failed-run.ts                   # most recent failed run

These wrap gh run list, gh run view --log-failed, and similar. You need gh auth status to be authenticated.

Scripts are TypeScript and cross-platform. All invocations use pnpm exec tsx, which resolves the declared local dependency and fails if dependencies are absent. gh CLI is cross-platform.

Triage decision tree

flowchart TD
  red{Run is red?} --> workflow{Which workflow?}
  workflow --> ci[ci.yml]
  workflow --> publish[publish.yml]
  workflow --> electron[ci-electron.yml]
  workflow --> other[Other workflow]
  ci --> common[Tests, lint, build<br/>references/common-failures.md]
  other --> taxonomy[references/workflow-taxonomy.md]
  publish --> releaseJob{Which release job?}
  releaseJob --> tag[tag-and-push]
  releaseJob --> npmOrder[publish: npm ordering]
  releaseJob --> matrix[electron: matrix leg]
  releaseJob --> assets[github-release: asset collision]
  electron --> smoke[On-demand Electron smoke<br/>never publish]

Release pipeline — publish.yml

The release flow uses a gated 7-job graph:

flowchart LR
  resolve[resolve] --> checks[ci-checks]
  resolve --> smoke[smoke via _smoke.yml]
  checks --> tag[tag-and-push]
  smoke --> tag
  tag --> publish[publish packages]
  publish --> electron[electron via _electron-build.yml]
  electron --> release[github-release]

Tag-push runs skip tag-and-push; publish.if accepts that skip while still requiring checks and smoke. Do not remove needs: [resolve, publish] from electron. The bundled server installs the just-published packages. Locked by packages/shared/src/__tests__/publish-workflow-contract.test.ts.

Full walkthrough with per-job failure modes: references/release-pipeline.md.

Known failure modes

Maintained in references/common-failures.md. Headline catalog:

FailureWhereDiagnosisFix
verify-lockfile-versions.mjs failstag-and-pushCross-ref specifier in lockfile doesn't match bumped versionRegenerate lockfile + commit; or fix scripts/sync-versions.js
CHANGELOG already has ## [X.Y.Z]tag-and-pushYou're re-dispatching with a version that was already promotedBump to a new version, or revert the CHANGELOG section
npm publish 403publishOIDC trusted publisher not configured for that packageConfigure in npm web UI; or temporarily use NPM_TOKEN
Electron matrix leg failselectronMissing prebuild for node-pty/better-sqlite3 on that OS/archCheck bundle-server.mjs GO/NO-GO guard; rebuild prebuilds
shell: bash on Windows runneranyLint test no-bash-on-windows.test.ts flags itRemove shell: bash or guard with if: runner.os != 'Windows'
Electron job missing needs:repo-lintpublish-workflow-contract.test.ts failedRestore needs: [resolve, publish]
Cannot find module @blackbelt-technology/... in electronelectronpublish job didn't run or failed; bundled server can't resolve from npmCheck publish job — re-run only if it failed; never bypass
Fastify crashes in bundled server smokeany using nodeBad Node version pinned in workflowBump node-version: to ≥ 22.18.0
Loud-but-harmless EADDRINUSE in smokesmoke jobConcurrent server spawnsUsually self-recovering; check next log lines
electron + github-release SKIPPED despite green publishelectronTag-push path skips tag-and-push; a skipped needs-ancestor poisons electron's DEFAULT if: success()Give electron explicit if: ${{ !cancelled() && needs.publish.result == 'success' }} (mirrors publish's guard). First hit v0.6.1
✗ koffi prebuild GO/NO-GO failed at ...koffi\build\koffi\win32_x64\koffi.nodeelectron (both win32 legs)koffi@3.x ships the prebuild at @koromix/koffi-win32-x64/win32_x64/koffi.node; the 2.x koffi/build/... path is never createdUpdate bundle-server.mjs guard to check the 3.x @koromix path first, 2.x fallback. First hit v0.6.1
arm64 NSIS smoke: pi-dashboard.exe not found ... after 150selectron (win32-arm64)x64 runner can't execute an arm64 Setup.exe/app, so silent install extracts nothingGuard the NSIS install-smoke step if: matrix.platform == 'win32' && matrix.arch == 'x64'. arm64 installer still builds+ships. First hit v0.6.1

Reading gh logs efficiently

# Last 10 runs (all workflows, this branch)
gh run list -L 10

# Last 5 failed runs across all workflows
gh run list -L 50 | grep -E 'failure|cancelled' | awk 'NR <= 5'

# Get a specific run, only the failed steps
gh run view <run-id> --log-failed

# Watch a running workflow (live tail)
gh run watch <run-id>

# Re-run only the failed jobs (preserves successful ones, saves CI time)
gh run rerun <run-id> --failed

# Re-run from scratch (rare; usually for flakes)
gh run rerun <run-id>

# Cancel a stuck run
gh run cancel <run-id>

gh run view --log-failed is the highest-leverage one — it pulls only failed-step output, which is what you want 95% of the time.

Never bypass the release pipeline with a manual npm publish. That loses OIDC trusted publishing, lockfile synchronization, changelog promotion, smoke gates, and Electron dependency ordering.

Rerun gotcha (tag-push releases): gh run rerun <id> --failed does NOT re-dispatch skipped downstream reusable-workflow jobs (e.g. electron) even after publish flips green — they stay skipped. After a smoke-gate flake on a tag-push release, re-push the tag for a clean single-pass run instead: git push --delete origin vX.Y.Z && git push origin vX.Y.Z. publish is idempotent (skips already-published packages), so re-pushing the tag is safe.

When the failure is repo-lint

Repo-lint tests fail the ci job specifically. They're listed in debug-dashboard/references/test-failure-triage.md → "Repo-lint tests". Fix the file that violated the rule. Don't loosen the lint — each one exists because of a real regression.

Related skills

  • release-cut — trigger a release (cuts the tag that fires publish.yml)
  • release-revoke — rollback / yank a release
  • debug-dashboard — when the bug only reproduces locally
  • implement — back to writing the fix
  • code-review — review the fix before re-pushing

Signals

GitHub stars
283
Forks
41
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
ci-troubleshoot
Source
github.com/blackbelttechnology/pi-agent-dashboard