Official agent skill

Try Fix Alternative Approach

by dotnet in dotnet/maui

Attempts one alternative fix for a bug, runs the given test command against it and reports what happened, always differing from existing PR fixes.

OfficialMITAuto-check passedDevelopment

Install Try Fix Alternative Approach

skills CLI
$ npx skills add dotnet/maui --skill try-fix -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install dotnet/maui try-fix --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/dotnet/maui.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.github/skills/try-fix .claude/skills/try-fix && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
try-fix
GitHub stars
23k
Token cost
~8.4k tokens
SKILL.md length
3,369 words
Files
5 (incl. references)
Skills in repo
27
Repo updated
First seen
Licence
MIT

At a glance

Attempts one alternative fix for a bug, runs the given test command against it and reports what happened, always differing from existing PR fixes.

  • Works in 11 steps: Understand the Problem and Review… → Establish Baseline (MANDATORY) → Analyze Target Files → …
  • CI or an agent needs an independent alternative to an existing PR fix
  • SKILL.md covers Activation Guard, Core Principles, ⚠️ CRITICAL: Sequential… and Inputs, plus 6 more sections
  • Calls git, pwsh and dotnet

What it does

Each run tries exactly one fix idea. The caller supplies a problem description, a test command, target files and optional hints, and the agent reviews the fixes already in the PR, picks a different approach, implements it, tests it and reports the outcome. It is for proposing and testing fixes only, so it should stay idle for code review, PR summaries, test-only requests or general questions, and when no problem or test command is given.

The agent works only from the context it receives and git history, with no outside searching. Cleanup is limited to one restore script, EstablishBrokenBaseline.ps1 with -Restore, and git checkout, clean, reset and stash are off limits. After the baseline step it may edit only the files listed under RevertedFiles in .github/.baseline-state.json, reports Blocked if another tracked file would be needed, and leaves untracked paths that existed beforehand alone. Reference files cover compile errors and an example invocation, and the excerpt stops partway through the principles.

When your agent uses it

  • CI or an agent needs an independent alternative to an existing PR fix
  • Testing a different fix approach for a bug against a given test command
  • Comparing several fix attempts by their measured results

Example prompts

  • “Try a different fix for the layout crash in this PR and run the UI test command to check it.”
  • “Attempt one alternative approach to this bug and report whether the tests pass.”

Requirements

  • PowerShell and git
  • A .NET MAUI build environment
  • An Android or iOS device or emulator
  • Compatibility (from SKILL.md): Requires PowerShell, git, .NET MAUI build environment, Android/iOS device or emulator

Workflow steps

11 steps, taken from the step headings in SKILL.md.

  1. Understand the Problem and Review Existing Fixes
  2. Establish Baseline (MANDATORY)
  3. Analyze Target Files
  4. Design ONE Fix
  5. Apply the Fix
  6. Expert Self-Review (MANDATORY — runs BEFORE testing)
  7. Test and Iterate (MANDATORY)
  8. 5: Refresh Self-Review If Code Changed (MANDATORY)
  9. Capture Artifacts (MANDATORY)
  10. Restore Working Directory (MANDATORY — runs even if Step 8 gate failed)
  11. Report Results

What it can do on your machine

Read from SKILL.md and the folder at commit 7d38fd0. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • git
    • pwsh
    • dotnet

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md. Its commands use git, which can reach the network depending on how they are called.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

  • Compatibility

    Requires PowerShell, git, .NET MAUI build environment, Android/iOS device or emulator

    From compatibility in the SKILL.md frontmatter.

Context cost

Try Fix Alternative Approach loads about 8.4k tokens when it runs, and up to ~9.2k if it reads all its reference files. Until then it costs about 75 tokens; SKILL.md has 3,369 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~75
When it runs · the whole SKILL.md, loaded when a task matches
~8.4k
With references · SKILL.md plus every file in references/, read only if the agent opens them
~9.2k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from dotnet/maui at commit 7d38fd0, republished under its MIT licence (© dotnet). 3,369 words, ~8,377 tokens.

Download SKILL.mdSave it as .claude/skills/try-fix/SKILL.md (or your agent's skills folder). This skill also uses 4 other files; get the full folder from GitHub.
name
try-fix
description
Attempts ONE alternative fix for a bug, tests it empirically, and reports results. ALWAYS explores a DIFFERENT approach from existing PR fixes. Use when CI or an agent needs to try independent fix alternatives. Invoke with problem description, test command, target files, and optional hints.
compatibility
Requires PowerShell, git, .NET MAUI build environment, Android/iOS device or emulator

Try Fix Skill

Attempts ONE fix for a given problem. Receives all context upfront, tries a single approach, tests it, and reports what happened.

Activation Guard

🚨 This skill is ONLY for proposing and testing code fixes. Do NOT activate for:

  • Code review requests ("review this PR", "check code quality")
  • PR summaries or descriptions ("what does this PR do?")
  • Test-only requests ("run tests", "check CI status")
  • General questions about code or architecture

If the prompt does not include a problem to fix and a test command to verify, this skill should not run.

Core Principles

  1. Always run once activated - Never question whether to run. The invoker decides WHEN, you decide WHAT alternative to try
  2. Single-shot - Each invocation = ONE fix idea, tested, reported
  3. Alternative-focused - Always propose something DIFFERENT from existing fixes (review PR changes first)
  4. Empirical - Actually implement and test, don't just theorize
  5. Context-driven - Work with what's provided and git history; don't search external sources
  6. Script-only restoration - The ONLY permitted cleanup command is pwsh .github/scripts/EstablishBrokenBaseline.ps1 -Restore. Never use git checkout, git clean, git restore, git reset, or git stash to revert or clean changes, including after artifacts have been captured.
  7. Baseline-file boundary - After Step 2, modify ONLY files listed in .github/.baseline-state.json under RevertedFiles. The restore script tracks only those original fix files; editing any other tracked file makes restoration incomplete. If the state file is absent, or its NewFiles array is non-empty, report Blocked before editing: added production files are not safely restorable. If the approach requires another tracked file, report Blocked instead of editing it.
  8. Preserve pre-existing untracked paths - Never modify or delete an untracked file or directory that existed before the attempt. Evaluators may inject the loaded skill as an untracked directory such as try-fix/; leave it exactly as found even when git status --short lists it. It is harness-owned input, not attempt-created drift. The restore script is the only cleanup step; do not use rm, Remove-Item, or another filesystem command to make the worktree appear clean.
  9. Wait for command completion - If a shell tool reports that a command is still running and returns a shellId, call read_bash with that exact shellId and wait for the completed result. Never proceed, report, or end the session while baseline, test, artifact, self-review, or restore work is still running.
  10. Contain attempt artifacts - Create every log, snapshot, state marker, and scratch file under $OUTPUT_DIR. Never persist $OUTPUT_DIR or other shell state in .github/, the repository root, or another workspace path. Shell variables do not persist between tool calls, so redeclare the same literal $OUTPUT_DIR at the start of each later shell command instead of writing a repository marker file.

Every invocation runs all 11 Workflow steps below. Step 6 (Expert Self-Review) is performed inline against .github/agents/maui-expert-reviewer.md — do NOT spawn the @maui-expert-reviewer sub-agent. Step 7.5 refreshes the self-review if the test loop modified code so the recorded findings reflect the final diff. Step 8 enforces this via a file-existence gate on reviewer-findings.json. Before returning the final report, verify that Step 9 ran with the exact script-only restore command above; if it did not, run it before responding.

⚠️ CRITICAL: Sequential Execution Only

🚨 Try-fix runs MUST be executed ONE AT A TIME - NEVER in parallel.

Why: Each try-fix run:

  • Modifies the same target source files
  • Uses the same device/emulator for testing
  • Runs EstablishBrokenBaseline.ps1 which reverts files to a known state

If run in parallel:

  • Multiple agents will overwrite each other's code changes
  • Device tests will interfere with each other
  • Baseline script will conflict, causing unpredictable file states
  • Results will be corrupted and unreliable

Correct pattern: Run attempt-1, wait for completion, then run attempt-2, etc.

Inputs

All inputs are provided by the invoker (CI, agent, or user).

InputRequiredDescription
ProblemYesDescription of the bug/issue to fix
Test commandYesRepository-specific script to build and test. Use BuildAndRunHostApp.ps1 for UI tests, Run-DeviceTests.ps1 for device tests, or dotnet test for unit tests. The correct command is determined by the test type detected in the PR. ALWAYS use the appropriate script - NEVER manually build/compile.
Target filesYesFiles to investigate; any file absent from the baseline state's RevertedFiles is read-only
PlatformYesTarget platform (android, ios, windows, maccatalyst)
HintsOptionalSuggested approaches, prior attempts, or areas to focus on
BaselineOptionalGit ref or instructions for establishing broken state (default: current state)

Outputs

Results reported back to the invoker:

FieldDescription
approachWhat fix was attempted (brief description)
files_changedWhich files were modified
resultPass, Fail, or Blocked
analysisWhy it worked, or why it failed and what was learned
diffThe actual code changes made (for review)
findings_countNumber of self-review findings recorded (0 = clean self-review)

Output Structure (MANDATORY)

FIRST STEP: Create output directory before doing anything else.

powershell
# Set issue/PR number explicitly (from branch name, PR context, or manual input)
$IssueNumber = "<ISSUE_OR_PR_NUMBER>"  # Replace with actual number

# Find next attempt number
$tryFixDir = "CustomAgentLogsTmp/PRState/$IssueNumber/PRAgent/try-fix"
$existingAttempts = (Get-ChildItem "$tryFixDir/attempt-*" -Directory -ErrorAction SilentlyContinue).Count
$attemptNum = $existingAttempts + 1

# Create output directory
$OUTPUT_DIR = "$tryFixDir/attempt-$attemptNum"
New-Item -ItemType Directory -Path $OUTPUT_DIR -Force | Out-Null

Write-Host "Output directory: $OUTPUT_DIR"

Keep this path from the command output and redeclare it in each subsequent shell invocation, for example:

powershell
$OUTPUT_DIR = "CustomAgentLogsTmp/PRState/<ISSUE_OR_PR_NUMBER>/PRAgent/try-fix/attempt-1"

Do not create .github/.try-fix-output-dir, .try-fix-output-dir, or any equivalent repository marker. The only attempt artifacts belong under $OUTPUT_DIR.

Required files to create in $OUTPUT_DIR:

FileWhen to CreateContent
baseline.logAfter Step 2 (Baseline)Output from EstablishBrokenBaseline.ps1 proving baseline was established
approach.mdAfter Step 4 (Design)What fix you're attempting and why it's different from existing fixes
reviewer-findings.jsonAfter Step 6 (Self-Review), refreshed by Step 7.5JSON array of self-review findings — [] when clean. MUST reflect the final diff.
reviewer-findings.diffAfter Step 6 (Self-Review), refreshed by Step 7.5Snapshot of git diff at the time the self-review was written. Step 7.5 compares this to the post-test-loop diff to detect drift.
result.txtAfter Step 7 (Test)Single word: Pass, Fail, or Blocked
fix.diffAfter Step 7 (Test)Output of git diff showing your changes
test-output.logAfter Step 7 (Test)Full output from test command
analysis.mdAfter Step 8 (Capture)Why it worked/failed, insights learned, and a one-line self-review summary

Example approach.md:

markdown
## Approach: Geometric Off-Screen Check

Skip RequestApplyInsets for views completely off-screen using simple bounds check:
`viewLeft >= screenWidth || viewRight <= 0 || viewTop >= screenHeight || viewBottom <= 0`

**Different from existing fix:** Current fix uses HashSet tracking. This approach uses pure geometry with no state.

Example result.txt:

Pass

Completion Criteria

The skill is complete when:

  • Problem understood from provided context
  • ONE fix approach designed and implemented
  • Fix tested with provided test command (iterated up to 3 times if errors/failures)
  • Either: Tests PASS ✅, or exhausted attempts and documented why approach won't work ❌
  • Expert self-review performed inline (Step 6) and reviewer-findings.json written — [] if clean. Refreshed by Step 7.5 if the test loop modified code, so the saved findings reflect the final diff.
  • Analysis provided (success explanation or failure reasoning with evidence)
  • Artifacts saved to output directory (verified by Step 8 file-existence gate)
  • Baseline target files restored with no attempt-created changes; pre-existing untracked harness inputs remain untouched
  • Results reported to invoker (including findings_count)

🚨 CRITICAL: What counts as "Pass" vs "Fail"

ScenarioResultExplanation
Test command runs, tests pass✅ PassActual validation
Test command runs, tests fail❌ FailFix didn't work
Code compiles but no device available⚠️ BlockedDevice/emulator unavailable - report with explanation
Code compiles but test command errors❌ FailInfrastructure issue is still a failure
Code doesn't compile❌ FailFix is broken

NEVER claim "Pass" based on:

  • ❌ "Code compiles successfully" alone
  • ❌ "Code review validates the logic"
  • ❌ "The approach is sound"
  • ❌ "Device was unavailable but fix looks correct"

Pass REQUIRES: The test command executed AND reported test success.

If device/emulator is unavailable: Report result.txt = Blocked with explanation. Do NOT manufacture a Pass.

Exhaustion criteria: Stop after 3 iterations if:

  1. Code compiles but tests consistently fail for same reason
  2. Root cause analysis reveals fundamental flaw in approach
  3. Alternative fixes would require completely different strategy

Never stop due to: Compile errors (fix them), infrastructure blame (debug your code), giving up too early.

Session limits: Each try-fix invocation allows up to 3 compile/test iterations. The calling orchestrator controls how many invocations (attempts) to run per session (typically 4-5 as part of pr-review Phase 3).


Workflow

Step 1: Understand the Problem and Review Existing Fixes

MANDATORY: Review what has already been tried:

  1. Check for existing PR changes:

    bash
    git diff origin/main HEAD --name-only
    • Review what files were changed
    • Read the actual code changes to understand the current fix approach
  2. Review prior attempts if any are known:

    • Note which approaches failed and WHY
    • Note which approaches partially succeeded
  3. Identify what makes your approach DIFFERENT:

    • Don't repeat the same logic/pattern as existing fixes
    • Think of alternative approaches: different algorithm, different location, different strategy
    • If existing fix modifies X, consider modifying Y instead
    • If existing fix adds logic, consider removing/simplifying instead

Examples of alternatives:

  • Existing fix: Add caching → Alternative: Change when updates happen
  • Existing fix: Fix in handler → Alternative: Fix in platform layer

Review the provided context:

  • What is the bug/issue?
  • What test command verifies the fix?
  • What files should be investigated?
  • Are there hints about what to try or avoid?

Do NOT search for external context. Work with what's provided and the git history.

Step 2: Establish Baseline (MANDATORY)

🚨 ONLY use EstablishBrokenBaseline.ps1 — NEVER use git checkout, git restore, or git reset to revert fix files.

The script auto-restores any previous baseline, tracks state, and prevents loops. Manual git commands bypass all of this and WILL cause infinite loops in CI.

powershell
pwsh .github/scripts/EstablishBrokenBaseline.ps1 *>&1 | Tee-Object -FilePath "$OUTPUT_DIR/baseline.log"

If this command continues in the background, wait for its matching shellId with read_bash until it completes. The baseline is not established merely because the initial shell invocation returned.

Verify baseline was established:

powershell
Select-String -Path "$OUTPUT_DIR/baseline.log" -Pattern "Baseline established"

Read .github/.baseline-state.json after this command. Its RevertedFiles array is the complete modification allow-list for the attempt. Target files outside that array may be inspected but MUST NOT be edited. If the state file was not created, or NewFiles contains any path, report Blocked immediately and proceed to Step 9 without modifying tracked files; the restore script does not safely restore added production files.

If the script fails with "No fix files detected": Report as Blocked — do NOT switch branches.

If something fails mid-attempt: pwsh .github/scripts/EstablishBrokenBaseline.ps1 -Restore

Step 3: Analyze Target Files

Read the target files to understand the code.

Verify the platform code path before implementing. Check which platform-specific file actually executes for the target scenario:

  • Files named .iOS.cs compile for both iOS AND MacCatalyst
  • Files named .Android.cs only compile for Android
  • Some platforms use Legacy implementations (e.g., iOS NavigationPage uses NavigationPage.Legacy.cs, not MauiNavigationImpl) If unsure which code path runs, check AppHostBuilderExtensions or handler registration to confirm.

Key questions:

  • What is the root cause of this bug?
  • Where should the fix go?
  • What's the minimal change needed?
Step 4: Design ONE Fix

Based on your analysis and any provided hints, design a single fix approach:

  • Which file(s) to change
  • What the change is
  • Why you think this will work

"Different" means different ROOT CAUSE hypothesis, not just different code location.

  • ❌ Bad: PR checks adapter == null in OnMeasure; you check adapter == null in OnLayout (same root cause assumption — just a different call site)
  • ✅ Good: PR checks adapter == null; you prevent disposal from happening during measure (different root cause hypothesis)

If hints suggest specific approaches, prioritize those.

IMMEDIATELY create approach.md in your output directory:

powershell
@"
## Approach: [Brief Name]

[Description of what you're changing and why]

**Prior approach avoided:** [Name every relevant existing/prior approach, their shared failure mechanism, and why they failed, or N/A]

**Mechanism-level difference:** [Explain the full cause-to-effect chain showing why the new mechanism avoids that failure, not merely the code location]
"@ | Set-Content "$OUTPUT_DIR/approach.md"
Step 5: Apply the Fix

Implement your fix. Use git status --short and git diff to track changes.

Step 6: Expert Self-Review (MANDATORY — runs BEFORE testing)

🚨 You perform this self-review yourself. Do NOT spawn the @maui-expert-reviewer sub-agent. Step 8's file-existence gate enforces that reviewer-findings.json is written every attempt.

This step runs BEFORE testing so you can catch design flaws before spending time on build+test cycles.

Procedure:

  1. Read the rules. View these specific sections of .github/agents/maui-expert-reviewer.md:

    • ## Overarching Principles (8 numbered principles, near the top of the file) — apply to every fix
    • ## Dimension Routing + ### Always-Active Dimensions — pick the dimensions that match your changed files
    • For each routed dimension, jump to its CHECK list under ## Review Dimensions (e.g., ### 1. Layout Measure-Arrange Correctness)

    You only need the dimensions that match the files you actually touched plus the always-active ones — typically 3–6 sections, not all 30.

  2. Identify your changed files:

    powershell
    git diff --name-only HEAD

    If you have NO code changes (e.g., Blocked because no device available before any fix was applied), still proceed to step 4 and write '[]' — the artifact gate is the enforcement mechanism.

  3. Walk your diff against the rules:

    • For each Overarching Principle → does your diff violate it?
    • For each routed dimension → walk every CHECK rule against the relevant hunks
    • Always-Active dimensions (Logic and Correctness, Regression Prevention, Complexity Reduction) → apply regardless of file paths
    • Be honest. If unsure, flag it.
  4. Write findings to $OUTPUT_DIR/reviewer-findings.json. Always write the file, even when there are zero findings. Use the same JSON format as the @maui-expert-reviewer agent (matches the GitHub Pull Request Review API):

    powershell
    # No findings — clean self-review (or no diff to review):
    '[]' | Set-Content "$OUTPUT_DIR/reviewer-findings.json"
    
    # With findings — JSON array of {path, line, body}:
    @'
    [
      {
        "path": "src/Core/src/Handlers/ScrollView/ScrollViewHandler.iOS.cs",
        "line": 42,
        "body": "**[major] Layout Measure-Arrange** — Content measured with unconstrained height but arranged with bounded height. Concrete scenario: ScrollView inside a Grid with Star row height."
      }
    ]
    '@ | Set-Content "$OUTPUT_DIR/reviewer-findings.json"

    Each entry has exactly 3 fields:

    • path (string) — file relative to repo root, must be a file present in your diff
    • line (integer ≥ 1) — line number on the changed (right) side of the diff. The line MUST appear in your diff — picking an unchanged line is wrong. Use 1 only as a fallback for file-level concerns where no single line captures the issue (e.g., missing import, structural concern).
    • body (string) — format **[severity] Dimension** — description. Severity is one of critical/major/moderate/minor.
  5. Validate the JSON parses and capture the count:

    powershell
    try {
        $findings = @(Get-Content "$OUTPUT_DIR/reviewer-findings.json" -Raw | ConvertFrom-Json)
        $findingsCount = $findings.Count
        Write-Host "✅ reviewer-findings.json: $findingsCount findings"
    } catch {
        Write-Host "❌ reviewer-findings.json is invalid JSON: $_"
        throw
    }
    
    # Snapshot the diff that was reviewed — Step 7.5 uses this to detect whether the test loop mutated code.
    # Use Set-Content -Value with Out-String so the file is created even when the diff is empty
    # (a bare `git diff | Set-Content` does NOT create the file when the pipe is empty).
    Set-Content -Path "$OUTPUT_DIR/reviewer-findings.diff" -Value (git diff | Out-String) -NoNewline

    Remember $findingsCount — you will report it as findings_count in Step 10 and summarize it in analysis.md (Step 8).

  6. Fix critical/major findings BEFORE testing:

    • If there are any [critical] or [major] findings → apply fixes for them in a single batch and rewrite reviewer-findings.json to reflect the new diff.
    • All [moderate] and [minor] findings → note in analysis.md (Step 8); do NOT iterate.
    • Only ONE correction round. Then proceed to Step 7 (Test).

Threshold guidance. Only record findings with a concrete failing scenario. Stylistic preferences and bikeshedding (see the ## What NOT to Flag table in maui-expert-reviewer.md) are not findings. An empty [] is the correct output for a clean fix — do not invent findings to fill the file.

Why before testing? Self-review catches design flaws (wrong null check, missing platform guard, thread safety issue) before you spend 5-15 minutes on a build+test cycle. It also runs when context is lightest — before test output floods the context window.

Show full SKILL.md (1,265 more words)Show less
Step 7: Test and Iterate (MANDATORY)

🚨 CRITICAL: ALWAYS use the provided test command script - NEVER manually build/compile.

For .NET MAUI repository: Use the test script matching the test type:

Test TypeCommand
UITestpwsh .github/scripts/BuildAndRunHostApp.ps1 -Platform <platform> -TestFilter "<filter>"
DeviceTestpwsh .github/skills/run-device-tests/scripts/Run-DeviceTests.ps1 -Project <project> -Platform <platform> -TestFilter "<filter>"
UnitTestdotnet test <project.csproj> --filter "<filter>"
powershell
# Capture output to test-output.log while also displaying it
# Example for UI tests:
pwsh .github/scripts/BuildAndRunHostApp.ps1 -Platform <platform> -TestFilter "<filter>" *>&1 | Tee-Object -FilePath "$OUTPUT_DIR/test-output.log"

# Example for device tests:
pwsh .github/skills/run-device-tests/scripts/Run-DeviceTests.ps1 -Project <project> -Platform <platform> -TestFilter "<filter>" *>&1 | Tee-Object -FilePath "$OUTPUT_DIR/test-output.log"

Testing Loop (Iterate until SUCCESS or exhausted):

  1. Run the test command - It will build, deploy, and test automatically
  2. Check the result:
    • ✅ Tests PASS → Move to Step 7.5 (Refresh self-review if needed)
    • ❌ Compile errors → Fix compilation issues (see below), go to step 1
    • ❌ Tests FAIL (runtime) → Analyze failure, fix code, go to step 1
  3. Maximum 3 iterations - If still failing after 3 attempts, analyze if approach is fundamentally flawed
  4. Document why - If exhausted, explain what you learned and why the approach won't work

Behavioral constraints:

  • ⚠️ NEVER blame "test infrastructure" - assume YOUR fix has a bug
  • Compile errors mean "work harder" - not "give up"
  • DO NOT manually build - always rerun the test command script

See references/compile-errors.md for error patterns and iteration examples.

Step 7.5: Refresh Self-Review If Code Changed (MANDATORY)

🚨 The test loop in Step 7 may modify code (compile-error fixes, runtime-error fixes). When that happens, the reviewer-findings.json written in Step 6 describes a stale diff — not the diff that will be captured in Step 8 and shipped to the reviewer. This step re-runs the self-review against the final diff so the recorded findings always correspond to the actual fix.

Procedure:

  1. Detect drift. Compare the current working-tree diff against the diff Step 6 reviewed.

    powershell
    # Force both sides to a single string. `git diff` assigned to a variable is a string[]
    # (one element per line); `-ne` between an array and a scalar is element-wise filtering,
    # not equality. Both must be normalized to the same shape before comparison.
    #
    # Also: `Get-Content -Raw` on a 0-byte file returns $null, not "". The Step 6 snapshot
    # creates a 0-byte file when the diff is empty (the documented Blocked-with-no-diff path),
    # so coalesce $null to "" via `?? ''` to avoid a false-positive "" -ne $null drift detection.
    $currentDiff  = (git diff | Out-String)
    $reviewedDiff = if (Test-Path "$OUTPUT_DIR/reviewer-findings.diff") {
        (Get-Content "$OUTPUT_DIR/reviewer-findings.diff" -Raw) ?? ''
    } else { '' }
    
    $diffChanged = ($currentDiff -ne $reviewedDiff)
    if (-not $diffChanged) {
        Write-Host "✅ Diff unchanged since Step 6 — self-review still current. Skip sub-steps 2 and 3."
    } else {
        Write-Host "🔁 Code changed during Step 7 — refreshing self-review against final diff..."
    }
  2. If $diffChanged is $true, re-do the Step 6 self-review against the new diff. This is YOU walking the rules again — it is not something the script does. Repeat the same procedure from Step 6:

    1. Re-list changed files: git diff --name-only HEAD
    2. Re-walk the rules in .github/agents/maui-expert-reviewer.md — every Overarching Principle, the always-active dimensions, and any routed dimensions whose file paths now match.
    3. Rewrite $OUTPUT_DIR/reviewer-findings.json with the new findings (or '[]' if clean). The file MUST be overwritten — appending or leaving the old content is a bug. Use the same JSON schema documented in Step 6.
  3. Re-snapshot and re-validate. Only after rewriting the JSON in sub-step 2, run:

    powershell
    # Re-snapshot the diff (matches Step 6's snapshot logic — works for empty diffs too).
    Set-Content -Path "$OUTPUT_DIR/reviewer-findings.diff" -Value (git diff | Out-String) -NoNewline
    
    # Re-validate the JSON parses and capture the new count.
    try {
        $findings = @(Get-Content "$OUTPUT_DIR/reviewer-findings.json" -Raw | ConvertFrom-Json)
        $findingsCount = $findings.Count
        Write-Host "✅ reviewer-findings.json refreshed: $findingsCount findings"
    } catch {
        Write-Host "❌ reviewer-findings.json is invalid JSON: $_"
        throw
    }

    Why no programmatic "did you actually rewrite the JSON" check? A SHA256 hash sentinel rejects the legitimate byte-identical case (e.g., [] → [] after a small compile fix that introduces no new violations), and that case is common. The procedural enforcement is sub-step 2's explicit numbered list above, plus the example-invocation chain that walks the dimensions explicitly. If sub-step 2 is skipped, the JSON validates but ships a stale review — accept that risk in exchange for not blocking valid clean fixes.

Severity handling is the same as Step 6. If the refresh surfaces new [critical] or [major] findings, you may apply ONE more fix batch and re-run the test loop, then re-refresh. Do not loop indefinitely — if a fix introduces critical findings on the third pass, mark the attempt Blocked and explain in analysis.md.

Step 8: Capture Artifacts (MANDATORY)

Before reverting, save ALL required files to $OUTPUT_DIR:

powershell
# 1. Save result (MUST be exactly "Pass", "Fail", or "Blocked")
"Pass" | Set-Content "$OUTPUT_DIR/result.txt"  # or "Fail"

# 2. Save the diff (use Set-Content -Value with Out-String so the file is created
#    even when the diff is empty — a bare `git diff | Set-Content` does not create
#    the file when the pipe is empty, which would fail the artifact gate.)
Set-Content -Path "$OUTPUT_DIR/fix.diff" -Value (git diff | Out-String) -NoNewline

# 3. Save test output (should already exist from Step 7)
# Copy-Item "path/to/test-output.log" "$OUTPUT_DIR/test-output.log"

# 4. reviewer-findings.json should already exist from Step 6 (and may have been refreshed by Step 7.5)
# 4b. reviewer-findings.diff snapshot (used by Step 7.5 to detect drift)

# 5. Save analysis (include a one-line summary of self-review findings)
@"
## Analysis

**Result:** Pass/Fail/Blocked

**What happened:** [Description of test results]

**Why it worked/failed:** [Root cause analysis]

**Self-review:** [N findings: brief summary of each, or "clean — no findings"]

**Insights:** [What was learned that could help future attempts]
"@ | Set-Content "$OUTPUT_DIR/analysis.md"

Verify all required files exist (this is the enforcement gate for Steps 6 and 7 — primarily reviewer-findings.json from Step 6, refreshed by Step 7.5 if needed):

🚨 The artifact check below MUST be wrapped so that Step 9 (Restore) ALWAYS runs even if the check fails. A failed gate that skips restore would leave the worktree dirty and corrupt the next sequential try-fix attempt.

powershell
# Run the file-existence check, but DEFER any throw until after Step 9 has restored the worktree.
$missing = @()
@("baseline.log", "approach.md", "result.txt", "fix.diff", "analysis.md", "test-output.log", "reviewer-findings.json", "reviewer-findings.diff") | ForEach-Object {
    if (Test-Path "$OUTPUT_DIR/$_") {
        Write-Host "✅ $_"
    } else {
        Write-Host "❌ MISSING: $_"
        $missing += $_
    }
}

# Record the gate result for use after Step 9 — DO NOT throw here.
if ($missing.Count -gt 0) {
    $gateFailureMessage = "Required artifacts missing: $($missing -join ', '). If 'reviewer-findings.json' is missing, Step 6 (Expert Self-Review) was not performed (or Step 7.5 did not refresh it after the test loop) — it is mandatory and must contain at least '[]' that reflects the final diff."
    Write-Host "⚠️  ARTIFACT GATE FAILED — proceeding to Step 9 restore before reporting failure."
    Write-Host $gateFailureMessage
    "Blocked" | Set-Content "$OUTPUT_DIR/result.txt" -Force
} else {
    $gateFailureMessage = $null
}

If $gateFailureMessage was set: Step 9 still runs (do NOT skip it). After Step 9 restores the target files, surface the failure in Step 10's report — set result.txt to Blocked (already done above) and explain in analysis.md which artifact was missing. The next sequential attempt then starts from the same restored baseline state, including any pre-existing untracked harness inputs.

Analysis quality matters. Bad: "Didn't work". Good: "Fix attempted to reset state in OnPageSelected, but this fires after layout measurement. The cached value was already used."

Step 9: Restore Working Directory (MANDATORY — runs even if Step 8 gate failed)

ALWAYS restore, even if fix failed or Step 8 detected missing artifacts. Skipping restore corrupts the next sequential try-fix attempt.

bash
pwsh .github/scripts/EstablishBrokenBaseline.ps1 -Restore

If restore continues in the background, wait for its matching shellId with read_bash until it completes. When Step 2 created .github/.baseline-state.json, do not report the attempt or end the session until restore confirms Restored True. If Step 2 already reported Blocked before changing any files and verified that baseline state was never created because all fix files were new or no fix files were detected, the expected completion is No baseline state found with Restored False; accept that result only for those verified no-state paths and only when no attempt edits were made.

🚨 Use EstablishBrokenBaseline.ps1 -Restore — not git checkout, git restore, or git reset (see Step 2 for why).

After restoration, leave every pre-existing untracked path unchanged. In particular, an evaluator-loaded try-fix/ directory may remain visible in git status --short; do not delete it. Judge restoration by Restored True and by the absence of attempt-created changes to the allowed target files, not by forcing all untracked harness inputs out of the workspace.

Step 10: Report Results

Provide structured output to the invoker:

markdown
## Try-Fix Result

**Approach:** [Brief description of what was tried]

**Prior Approach Avoided:** [Name every relevant existing/prior approach, their shared failure mechanism, and why they failed, or N/A]

**Mechanism-Level Difference:** [Explain the full cause-to-effect chain showing why the new mechanism avoided that failure]

**Files Changed:**
- `path/to/file.cs` (+X/-Y lines)

**Result:** ✅ PASS / ❌ FAIL

**Self-Review:** N findings (X critical, Y major, Z moderate/minor) — see `reviewer-findings.json`

**Analysis:**
[Why it worked, or why it failed and what was learned]

**Diff:**
(paste `git diff` output here)

**This Attempt's Status:** Done/NeedsRetry
**Reasoning:** [Why this specific approach succeeded or failed]

The two approach-comparison fields must be self-contained prose, not labels or fragments. When prior attempts share a root cause, explicitly name that shared failure mechanism. Then connect the new mechanism to the failure with a causal explanation (for example, “because X now happens after Y, Z is available directly, so the failing fallback is never consulted”). Do not rely on the contents of approach.md or analysis.md being visible to the invoker.

Determining Status: Set Done when you've completed testing this approach (whether it passed or failed). Set NeedsRetry only if you hit a transient error (network timeout, flaky test) and want to retry the same approach.

Error Handling

SituationAction
Problem unclearReport "insufficient context" - specify what's missing
Test command fails to runReport build/setup error with details
Test times outReport timeout, include partial output
Can't determine fix approachReport "no viable approach identified" with reasoning
Git state unrecoverableRun pwsh .github/scripts/EstablishBrokenBaseline.ps1 -Restore (see Step 2/9)

Guidelines for Proposing Fixes

Good Fix Approaches

✅ Null/state checks - Guard against unexpected null or state ✅ Lifecycle timing - Move code to correct lifecycle event ✅ Cache invalidation - Reset stale cached values

Approaches to Avoid

❌ Massive refactors - Keep changes minimal ❌ Suppressing symptoms - Fix root cause, not symptoms ❌ Multiple unrelated changes - ONE focused fix per invocation


See references/example-invocation.md for a complete example with sample inputs.

© dotnet, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 4 other files (references) in .github/skills/try-fix of dotnet/maui.

  • SKILL.md
  • references/compile-errors.md
  • references/example-invocation.md
  • tests/eval.restore.vally.yaml
  • tests/eval.vally.yaml

Open the folder on GitHubat commit 7d38fd0

Compare with similar skills

Try Fix Alternative Approach next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Try Fix Alternative Approach compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Try Fix Alternative Approach this skilldotnet/maui23k—~8.4kAutomated safety check: PassMIT
Sokol Netelix22/Sokol.NET154—~2.8kAutomated safety check: PassMIT
Maui AI DebuggingRedth/Maui.Gtk101—~4.1kAutomated safety check: PassMIT
Pester Failure AnalysisPowerShell/PowerShell56k—~5.1kAutomated safety check: PassMIT
Debugging and Error Recoveryaddyosmani/agent-skills102k1 repos~2.6kAutomated safety check: PassMIT
CanvasBitterbot-AI/bitterbot-desktop2.5k—~1.4kAutomated safety check: PassMIT

Similar skills

  • Sokol Net

    elix22/Sokol.NET

    Sokol.NET framework development — use for ANY work in this repo: creating or debugging examples, building/running for desktop/Android/iOS/Web, writing or compiling shaders, adding a new C/C++…

    154 GitHub stars~2.8k tokensUpdated yesterday
    Game DevelopmentAuto-check passed
  • Maui AI Debugging

    Redth/Maui.Gtk

    End-to-end workflow for building, deploying, inspecting, and debugging .NET MAUI and MAUI Blazor Hybrid apps as an AI agent.

    101 GitHub stars~4.1k tokensUpdated 5 mo ago
    MobileAuto-check passed
  • Pester Failure Analysis

    PowerShell/PowerShell

    Investigates failing Pester tests in PowerShell CI jobs by following a six-step workflow from pull request status to documented fix recommendations.

    56k GitHub stars~5.1k tokensUpdated today
    Testing & QAAuto-check passed
  • Debugging and Error Recovery

    addyosmani/agent-skills

    Applies a stop-the-line rule and a step-by-step triage when tests fail, builds break or something stops working, aiming at the root cause instead of guesses.

    102k GitHub starsUsed in 1 repo~2.6k tokens
    DevelopmentAuto-check passed
  • Canvas

    Bitterbot-AI/bitterbot-desktop

    Display and control HTML content on connected Bitterbot nodes (Mac, iOS, Android) via the canvas host server.

    2.5k GitHub stars~1.4k tokensUpdated today
    DevelopmentAuto-check passed
  • Dogfood

    callstackincubator/agent-skills

    Official

    Systematically explore and test a mobile app on iOS/Android with agent-device to find bugs, UX issues, and other problems.

    1.7k GitHub starsUsed in 1 repo~1.7k tokens
    DevelopmentAuto-check passed

More from dotnet/maui

All 27 skills in this repo
  • Mines local Copilot CLI session logs for dotnet/maui to rank costly or failing runs, tag recurring failure modes, propose repo edits and emit guard evals.

    23k GitHub stars~3.4k tokensUpdated today
    Auto-check passed
  • Official

    Reviews the tests added in a pull request for fix coverage, quality, edge cases and test type, and recommends lighter test types where they would do.

    23k GitHub stars~2.9k tokensUpdated today
    Auto-check passed
  • Official

    Produces evidence-backed ship-readiness verdicts for .NET MAUI Servicing Releases and Previews, and drafts public-safe release handoff pages from the result.

    23k GitHub stars~15k tokensUpdated today
    Auto-check passed
  • Official

    Interprets pinned managed benchmark evidence for a dotnet/maui pull request and writes a narrative for the performance review workflow, without running or publishing anything.

    23k GitHub stars~2.4k tokensUpdated today
    Auto-check passed
  • PR Finalize

    dotnet/maui

    Official

    Checks that a pull request's title and description match its implementation and reviews the code for best practices before merge, without posting anything.

    23k GitHub stars~3.1k tokensUpdated today
    Auto-check passed
  • Official

    Adds MAUI-specific guardrails on top of the maestro-cli skill and Maestro MCP tools for darc, BAR, and channel or feed lookups in dotnet/maui.

    23k GitHub stars~10k tokensUpdated today
    Auto-check passed

Questions about Try Fix Alternative Approach

What does Try Fix Alternative Approach do?

Attempts one alternative fix for a bug, runs the given test command against it and reports what happened, always differing from existing PR fixes. Each run tries exactly one fix idea. The caller supplies a problem description, a test command, target files and optional hints, and the agent reviews the fixes already in the PR, picks a different approach, implements it, tests it and reports the outcome.

When should I use Try Fix Alternative Approach?

Try Fix Alternative Approach fits situations like: CI or an agent needs an independent alternative to an existing PR fix; testing a different fix approach for a bug against a given test command; comparing several fix attempts by their measured results.

How do I install Try Fix Alternative Approach in Claude Code?

Run `npx skills add dotnet/maui --skill try-fix -a claude-code`. Or copy the skill folder (.github/skills/try-fix in dotnet/maui) into .claude/skills/try-fix in your project. Claude Code loads it when a task matches its description.

How do I install Try Fix Alternative Approach in Codex?

Run `npx skills add dotnet/maui --skill try-fix -a codex`. Or copy the skill folder (.github/skills/try-fix in dotnet/maui) into .agents/skills/try-fix in your project. Codex loads it when a task matches its description.

Can I use Try Fix Alternative Approach in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add dotnet/maui --skill try-fix -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/try-fix, .gemini/skills/try-fix, .github/skills/try-fix and .opencode/skills/try-fix in your project.

What does Try Fix Alternative Approach need to run?

Going by SKILL.md and its folder, Try Fix Alternative Approach needs the command-line tools its instructions call (git, pwsh and dotnet). Our summary lists: PowerShell and git; A .NET MAUI build environment; An Android or iOS device or emulator. Compatibility (from SKILL.md): Requires PowerShell, git, .NET MAUI build environment, Android/iOS device or emulator.

Does Try Fix Alternative Approach access the network?

SKILL.md contains no URLs. Its commands use git, which can reach the network depending on how they are called. This is read from the text; nothing was executed.

Is Try Fix Alternative Approach safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Try Fix Alternative Approach use?

Try Fix Alternative Approach is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Try Fix Alternative Approach use?

About 8.4k tokens (SKILL.md is roughly 34k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 850 tokens, read only when the agent opens those files.

What are the alternatives to Try Fix Alternative Approach?

Skills that share tags, products or a category with Try Fix Alternative Approach: Sokol Net (elix22/Sokol.NET, 154 stars), Maui AI Debugging (Redth/Maui.Gtk, 101 stars), Pester Failure Analysis (PowerShell/PowerShell, 56k stars) and Debugging and Error Recovery (addyosmani/agent-skills, 102k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Try Fix Alternative Approach?

dotnet (a GitHub organization, an official publisher) maintains it in dotnet/maui, which has 23,322 GitHub stars. The repository holds 27 skills in this directory. The repository was last updated on October 7, 2026.

Source: dotnet/maui on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.