diagnose-deployment
This Claude Code skill diagnoses Power Pages deployment failures by collecting project artifacts, verifying prerequisites like PAC CLI and authentication status, and pattern-matching errors against a known failure catalog. Use it when deployment fails to systematically identify root causes and apply user-approved fixes, working offline when necessary while optionally grounding findings in current Microsoft Learn documentation.
git clone --depth 1 https://github.com/microsoft/power-platform-skills /tmp/diagnose-deployment && cp -r /tmp/diagnose-deployment/plugins/power-pages/skills/diagnose-deployment ~/.claude/skills/diagnose-deploymentSKILL.md
> **Plugin check**: Run `node "${CLAUDE_PLUGIN_ROOT}/scripts/check-version.js"` — if it outputs a message, show it to the user before proceeding.
# diagnose-deployment
Surfaces and pattern-matches deployment errors against a known failure catalog. For each identified error with an available auto-fix, asks explicit user permission before applying any changes. Never auto-applies fixes without confirmation.
## Prerequisites
- Project root with `powerpages.config.json`
- PAC CLI installed (will report if missing)
## Phases
### Phase 1 — Verify Prerequisites and Locate Project
**Create all tasks upfront at the start of this phase.**
Tasks to create:
1. "Verify prerequisites and locate project"
2. "Collect deployment artifacts"
3. "Surface upload errors"
4. "Query solution import status"
5. "Diagnose and categorize findings"
6. "Offer auto-fixes"
7. "Present findings summary"
Steps:
1. Locate project root: search for `powerpages.config.json` in cwd and parent directories
2. Check PAC CLI: `pac --version` (report version or "not installed")
3. Check PAC CLI auth: `pac env who` (report environment URL or "not authenticated")
4. Check Azure CLI: `az account show` (report subscription or "not logged in")
Auth failures are non-blocking — report them as findings, continue collecting other artifacts.
### Phase 1.5 — Ground in current ALM documentation
> Reference: `${CLAUDE_PLUGIN_ROOT}/references/alm-docs-grounding.md`
Cap this step at ~30 seconds. If MCP search / fetch errors out, log a one-line note and continue — this skill must remain runnable offline.
1. Run `microsoft_docs_search` with the query: `Power Pages deployment errors solution import troubleshooting`.
2. Fetch `https://learn.microsoft.com/en-us/power-platform/alm/solution-concepts-alm` (and at most one sister page on troubleshooting or known import errors) in parallel via `microsoft_docs_fetch`.
3. Extract a one-paragraph summary of what Microsoft Learn currently says about common deployment failures and their resolution. Compare against `${CLAUDE_PLUGIN_ROOT}/references/deployment-error-catalog.md` and flag any new error patterns not yet captured in the catalog.
4. Use the summary to inform pattern-matching in Phase 5. If a new pattern is documented on Learn that isn't in the catalog, surface it to the user as a candidate addition rather than silently extending the catalog.
### Phase 2 — Collect Deployment Artifacts
Gather all available context:
1. Read `powerpages.config.json` — extract `siteName`, `websiteRecordId`, `compiledPath`
2. Check `.powerpages-site/` folder exists
3. Glob for manifest files: `.powerpages-site/*-manifest.yml` — list all found, note their environment hostnames
4. Check if `.solution-manifest.json` exists (for solution-related diagnostics)
5. Check if `docs/alm/last-import.json` exists (for recent import failures)
6. Check build output: confirm `{compiledPath}/` exists and is non-empty
Report: "Found project: `{siteName}`. Artifacts collected."
### Phase 3 — Surface Upload Errors
Re-run `pac pages upload-code-site` in capture mode to get fresh error output:
```bash
pac pages upload-code-site --rootPath "." 2>&1
```
> **Note**: This intentionally triggers the upload to capture any errors. If the upload succeeds cleanly, that is also a valid diagnostic result ("no errors found").
Capture stdout+stderr as a single string. Pass to `scripts/parse-deployment-errors.js`:
```bash
echo "{escaped-output}" | node "${CLAUDE_PLUGIN_ROOT}/scripts/parse-deployment-errors.js"
```
Parse the JSON findings array. If the upload succeeded with no errors, note this and skip to Phase 5 with an empty findings list.
### Phase 4 — Query Solution Import Status
Only run if `.solution-manifest.json` exists.
1. Acquire Azure CLI token for environment URL
2. Check recent async operations (last 24 hours):
```
GET {envUrl}/api/data/v9.2/asyncoperations?$filter=statecode eq 3 and statuscode eq 31 and createdon gt {yesterday}&$select=asyncoperationid,name,message,friendlymessage,statuscode,completedon&$orderby=completedon desc&$top=5
```
3. Check recent import jobs:
```
GET {envUrl}/api/data/v9.2/importjobs?$select=solutionname,completedon,progress&$orderby=completedon desc&$top=3
```
4. If failed operations found, pass each `message` field through `parse-deployment-errors.js`
Skip gracefully if auth is not available (auth failure in Phase 1).
### Phase 5 — Auto-Diagnose Known Issues
Consolidate all findings from Phases 3 and 4. For each finding, categorize:
- **Error**: Blocks deployment
- **Warning**: May cause issues
- **Info**: Informational
Also add findings for missing artifacts discovered in Phase 2:
- Missing `websiteRecordId` → Error (patternId: `missing-website-record-id`)
- Empty build output → Error (patternId: `empty-build`)
- Multiple environment manifests → Warning (may indicate environment confusion)
Present all findings in a table:
| # | Severity | Type | Issue | Auto-fix? |
|---|---|---|---|---|
| 1 | Error | upload | JavaScript uploads blocked | Yes |
| 2 | Warning | config | Multiple manifest files found | No |
### Phase 6 — Offer Auto-Fixes
For each Error finding with `autoFixAvailable: true`, in order:
<!-- gate: diagnose-deployment:6.auto-fix | category=consent | cancel-leaves=nothing -->
> 🚦 **Gate (consent · diagnose-deployment:6.auto-fix):** Per-finding consent before applying any auto-fix. **Loops once per Error finding with `autoFixAvailable: true`** — each finding gets its own Yes / No / Skip-all `AskUserQuestion`. The pattern ID surfaces in the prompt. **Never batch fixes** — three findings = three separate consent prompts (unless the user picks "Skip all" on the first, which short-circuits the loop). The Yes from finding 1 does NOT cover finding 2; each fix has its own blast radius (different files, different settings, different reversibility).
1. Explain the issue and proposed fix
2. Ask explicit permission via `AskUserQuestion`:
> "Issue: {message}Guide the user to add a data source, connection, or API connector to a Canvas App via Power Apps Studio, then verify and continue. USE WHEN the user asks to add a data source, add a connection, add an API, add a connector, connect to SharePoint / Dataverse / SQL / Excel / OneDrive / Teams / Office 365, or any similar request to make new data available to the app. DO NOT USE WHEN the user is asking to list or describe existing data sources — call list_data_sources or list_apis directly instead.
Creates or edits a Power Apps Canvas App through the Canvas Authoring MCP coauthoring session. Handles new app generation from requirements, simple inline edits, and complex multi-screen changes with parallel screen builders. Triggers on requests to create, build, generate, modify, update, change, or edit a Canvas App or .pa.yaml files.
Configure the Canvas Authoring MCP server for the current coauthoring session. USE WHEN "configure MCP", "set up MCP server", "MCP not working", "connect Canvas Apps MCP", "canvas-authoring not available", "MCP not configured", "set up canvas apps". DO NOT USE WHEN prerequisites are missing — direct the user to install .NET 10 SDK first.
[DEPRECATED — use canvas-app instead] Generate a complete Power Apps canvas app.
>
Adds Azure DevOps connector to a Power Apps code app. Use when querying work items, creating bugs, managing pipelines, or making ADO API calls.
Adds any Power Platform connector to a Power Apps code app. Generic fallback for connectors not covered by a specific skill.
Adds a data source or connector to a Power Apps code app. Asks what the user wants to accomplish and routes to the appropriate specialized skill.