Install
openclaw skills install fixUser behavior correction skill. Triggered by "fix:" prefix feedback (e.g., "fix: why didn't you commit?"). Analyzes the mistake, improves the relevant prompt (skill/rule/agent/memory/hook) to prevent recurrence, then fixes the current issue. TodoWrite required for all steps. Use when "fix:", "fix this", "correct", "why not", "why missing", "behavior fix" is mentioned.
openclaw skills install fixActivated when user gives feedback with "fix:" prefix. Finds the root cause of the mistake, improves the relevant prompt (skill/rule/agent/memory/CLAUDE.md/hook), and fixes the current issue.
fix: prefix--plan: In Step 2, instead of modifying prompts directly, emit only the modification plan for user review before execution. Use for complex changes or changes spanning multiple files.Before any analysis or text output, register TODO items.
⚠️ CRITICAL — Do not delete prior fix tasks on chained /fix (HARD STOP):
When a new /fix arrives while a prior /fix's tasks are still pending/in_progress:
⚠️ CRITICAL — Preserve existing tasks when TaskCreate is unavailable (HARD STOP):
In sessions where TaskCreate is disconnected/unavailable, only TodoWrite is usable. TodoWrite takes an array and overwrites the entire todo list on every call — registering only 4 fix-* items will wipe all existing todos.
Self-check immediately before calling:
Correct pattern (pseudo-code; ...existing_8_tasks is a placeholder for the actual array of existing tasks read from the prior TodoWrite/TaskList output — substitute the real entries verbatim):
# If 8 existing tasks exist, call with a 12-item array adding fix-* 4
TodoWrite([
...existing_8_tasks, # ← replace with the actual 8 existing task objects, not a literal spread
{ content: "🔍 fix: {summary} — root cause analysis", status: "in_progress" },
{ content: "🔧 Root cause fix", status: "pending" },
{ content: "🔄 Resume original work: {one-line summary of original work}", status: "pending" },
{ content: "📋 Completion report + cleanup", status: "pending" },
])
Forbidden pattern (data loss):
# Ignoring existing tasks and registering only 4 fix-* → all existing tasks vanish
TodoWrite([
{ content: "🔍 fix: ...", status: "in_progress" },
{ content: "🔧 Root cause fix", status: "pending" },
{ content: "🔄 Resume original work: ...", status: "pending" },
{ content: "📋 Completion report + cleanup", status: "pending" },
]) # ❌ Existing task data is lost
Default form (when no existing tasks):
TodoWrite([
{ id: "fix-0", content: "🔍 fix: {user feedback summary} — root cause analysis", status: "in_progress" },
{ id: "fix-1", content: "🔧 Root cause fix", status: "pending" },
{ id: "fix-2", content: "🔄 Resume original work: {one-line summary of original work}", status: "pending" },
{ id: "fix-3", content: "📋 Completion report + cleanup", status: "pending" },
])
Antigravity (Gemini) Users: Create or update the task.md artifact representing the TODO list above. This fulfills the TodoWrite requirement.
In fix-2's {original work}, list the initial request plus everything in progress including the immediately preceding action
fix-2 = "Complete the original work with the revised approach" — the goal is the deliverable the user originally requested, not skill/rule changes themselves
Step 0 is the first tool call after /fix activation. Text output before TodoWrite = violation.
No trivial exception (HARD STOP): Even when the symptom is fixable with a 1-line change, 5-Why analysis is mandatory. code-workflow has a trivial skip, but fix's purpose is finding the structural cause on every invocation to prevent recurrence. Even for "simple typos / encoding issues", Why 1~3 must be written.
Recurrence pre-check (first step of Step 1):
Grep failed-attempts.md + rules files for prior records of the same patternConfirm existing rule coverage (CRITICAL — do not duplicate rules in fix.md):
The following rules apply automatically before entering the fix procedure (rules/ is always_on). Re-adding them to fix.md creates location errors and duplication:
ask-user-question.md "Forbid arbitrary action on unclear instructions" — when user instructions/statements admit multiple interpretations, AskUserQuestion is requiredcommon.md "Cross-verify state from multiple sources" — do not conclude from a single statement/output; verify at least 2 sourcescommon.md "Don't guess existing code's purpose/behavior — read it" — verify against primary sources (code, API, files)common.md "Glob/Grep before claiming absence/necessity" — claims of "doesn't exist / is needed" must follow code verificationIf Why analysis identifies the above rules as root cause, the rules themselves do not need to be modified — go deeper with Why 4-5 to ask "why was that rule ignored in the fix flow?". If the answer is "fix procedure forces a reactive flow" or "existing rules aren't applied automatically", do not trap the rule inside the fix skill — record it as a recurrence in failed-attempts.md (next candidate for hook automation).
Don't stop at the direct cause. Dig at least 3 levels deep:
Why 1: What went wrong? (symptom — the immediate mistake)
Why 2: Why did I make that decision? (judgment — missing knowledge/rule)
Why 3: Why was that knowledge/rule missing? (structural — skill/rule gap)
Completion gate — do NOT proceed to Step 1.5 until ALL of these are true:
Iterate over all Whys and explicitly enumerate the action for each. All entries in this list must be executed in Step 2 before Step 3 can proceed.
| Why | Target file | Action |
|-----|-------------|--------|
| Why 1 | (current issue — resolved in Step 3) | Step 3 Resume |
| Why 2 | git.md | Add rule: "Forbid alternative command selection on failure" |
| Why 3 | failed-attempts.md | Record 2nd recurrence |
| Why 4 | fix/SKILL.md | Strengthen Checkpoint |
| Why 5 | fix/SKILL.md | Add Step 1.5 (this change) |
Action types:
Step 2 Checkpoint verifies that every row in this table is completed.
Step 2 execution gate (HARD STOP): If Step 1 produced even one Why, Step 2 is mandatory. "Trivial, so no rule changes" is forbidden. You must perform at least one Edit/Write on the target file(s) identified by Why analysis before Step 3 can proceed. Zero Edit/Write = Step 2 not executed = procedure violation.
| # | Don't | Do |
|---|---|---|
| 1 | Write Why as inline text and skip Step 2 | Edit/Write every target file identified by Why |
| 2 | Assume "current issue is resolved, so Step 2 is unnecessary" | Resolving current issue = Step 3, recurrence prevention = Step 2. Both are mandatory |
| 3 | Shorten Step 2 in later fixes within a chain | Every /fix call is the same quality. No shortening by call count |
"Prompt" = any persistent text that influences Claude's behavior. Priority (check in order — stop at the first match):
| Priority | Target | Condition | Example |
|---|---|---|---|
| 1st | Skill (~/.claude/skills/, .claude/skills/) | Skill procedure incomplete or wrong | Fix procedure step missing |
| 2nd | Rule (~/.agent/rules/, .claude/rules/) | Behavior rule missing or insufficient | Add to failed-attempts.md |
| 3rd | Sub-agent (.claude/agents/*.md) | Agent prompt missing constraint | Add rule to agent description |
| 4th | Memory (memory/*.md) | Context/reference info missing | Add project/reference memory |
| 5th | CLAUDE.md / AGENTS.md | Project-level instruction gap | Add section |
| 6th | Hook (settings.json hooks) | Automation needed for repeated mistakes | Add PostToolUse hook |
Use Do & Don't table format (MANDATORY for 2+ recurrences): When adding or strengthening rules, use the Do & Don't table instead of prose. Placing forbidden patterns (Don't) next to correct alternatives (Do) raises scan speed and compliance. For rules that have recurred 2+ times, switching to a table is required.
| # | Don't | Do |
|---|-------|-----|
| 1 | {violation pattern} | {correct pattern} |
When fixing:
Escalation on recurrence (same pattern 2+ times):
~/.agents/.bak/ — no annotations or failed-hooks.md (a separate file, not failed-attempts.md)--plan mode:
Plan artifact .md saving (MANDATORY in --plan mode) — applies vibe-coding.md "Artifact path rules":
| Environment detection | Save path | Filename |
|---|---|---|
{workspace}/.ralph/docs/generated/ exists | .ralph/docs/generated/plan-fix-{slug}.md | slug = key keyword (e.g., consolidate-next-action) |
{workspace}/.omc/plans/ exists (no Ralph) | .omc/plans/plan-fix-{slug}.md | same |
| Neither exists | Confirm path via AskUserQuestion | — |
Chat output format (after saving artifact):
Plan saved: <absolute path>
Key summary:
- N target files
- Key changes ...
See the file above for details. Reply "apply" or with feedback.
Do not re-dump the entire plan body into chat — chat shows only path + 3-5 line summary.
| # | Don't | Do |
|---|---|---|
| 1 | Output --plan results only in chat and stop | Save .md to .ralph/docs/generated/ or .omc/plans/ and report the path |
| 2 | Save the artifact but also dump the full plan body in chat | Chat = path + 3-5 line summary only |
| 3 | Decide "it's just a draft, no need to save" | --plan = artifact. Always save |
Checkpoint (MANDATORY before proceeding to Step 3; in --plan mode, only after approval):
Verify that the targets identified at every Why level (1~5) were actually modified before completing Step 2:
This is the most important step. The user's original request must be completed — not just the fix itself.
3-0. Infer user intent (MANDATORY — execute before any mechanical task listing): From the user's /fix message (skill args) and session context, infer "what outcome does the user want":
| User message | Verification medium (use verbatim in Resume) |
|---|---|
| "/api/system-log?limit=30: HttpError" | curl <APP_URL>/api/system-log?limit=30 (with cookie) — verify response status/body |
| "500 on the login screen" | Playwright on sign-in screen → submit → verify response |
| "Error when clicking X button on page Y" | Playwright on page Y → click X button → verify result |
| "File upload failure" | Reproduce with the same file + same form data via multipart POST |
Example: /fix start with Critical + session shows code modified but not verified → "What the user wants: Playwright verification that the modified code actually works" + verification medium: the screen path the user reported (e.g., /dashboard/sso-callback)
Dismissal trigger keywords:
| User expression | Interpretation |
|---|---|
| "Just force push over there" | That remote/branch state is out of verification scope |
| "Forget about that" / "That's done" | Item handled or irrelevant — do not raise |
| "Don't worry about it" / "Skip" | That fact is irrelevant to the core work |
| "Already did it" / "Handled" | User handled it directly — no re-verification/re-reporting |
| "Why do you keep bringing up X" / "Again with X" | Annoyance at secondary mention of X in the prior response — return to core immediately |
| # | Don't | Do |
|---|---|---|
| 1 | Re-report dismissed items under the pretext of "fact verification" | Verification is limited to the core work medium. Even if dismissed items appear in git fetch/grep, exclude them from report text |
| 2 | Statements that "prove the user's guess wrong" | Do not fabricate something the user never said and refute it. Quote only what the user said |
| 3 | After dismissal, re-mention the same fact "for accuracy" once more | One dismissal = permanent silence. Same in all follow-up responses |
| 4 | Continue mentioning X despite annoyance signals ("damn", "why X again", "wtf") | Annoyance signal = ↑ ask priority + immediate return to core. Zero mention of dismissed items from the next response |
Self-check (every time before writing a response):
3-0.5. Re-call rejected AskUserQuestion (HARD STOP):
If the turn immediately before fix had AskUserQuestion rejected + /fix triggered as the flow, then after fix Resume removes the reject cause, re-calling ask with improved options is part of Step 3's deliverable. Do not autonomously decide "end without re-call".
| Reject reason | Can fix resolve it? | Resume handling |
|---|---|---|
| ask secondary issue (visual noise, stale context, inaccurate option description) | ✅ Yes | Remove cause in fix Step 2/3 → re-call ask with improved options |
| ask intent rejection (user denies the very intent to proceed) | ❌ No | No re-call. End with fix completion report |
| ask option mismatch (the options themselves are wrong) | ✅ Yes | Restructure options → re-call ask |
| ask timing mismatch (preconditions unmet) | ✅ Yes | Satisfy preconditions → re-call ask |
| # | Don't | Do |
|---|---|---|
| 1 | AskUserQuestion rejected → fix done → autonomously decide "end without re-call" | If fix resolved the reject cause, re-call with improved options. Reject ≠ permanent end |
| 2 | Default-interpret the reject reason as "user rejects the very intent" | Determine the reject reason from the user's immediate message (/fix args, annoyance signals). Distinguish intent rejection vs secondary issue |
| 3 | "We already asked once; let the user decide on their own" | A secondary issue that fix resolved leaves the user able to decide via ask. ask = decision trigger |
| 4 | Re-call by copy-pasting the rejected options verbatim | Reflect the reject cause in description (e.g., note "Summary cleaned up" → attestation the user can verify) |
| 5 | Avoid ask out of "re-call = nagging" thinking | Reporting reject-cause resolution + re-calling ask is not nagging. It restores user decision authority |
The user doesn't want to proceed with this tool use) → If no, skipPR #146 Step 8 next-action ask posted → user rejected + /fix why does the summary keep growing called → fix cleaned up to 1 Summary (from 3) → fix completion report autonomously decided "end without re-call". User pointed out: "When the immediate ask is rejected, fix should ask again with the improved direction". This Step 3-0.5 was added to resolve it.
3-1. Resume existing in_progress tasks (HARD STOP): If TaskList had in_progress/pending entries before entering fix, fix Step 3 must continue executing those tasks before fix can end. "Already in TaskList, so no need to separate" is not resume — actual execution is resume.
| # | Don't | Do |
|---|---|---|
| 1 | End fix saying "existing tasks are in TaskList, so no separation needed" | Continue executing existing in_progress tasks in fix Step 3 |
| 2 | Resume only fix-2's subject scope and ignore existing tasks | fix-2 + existing in_progress tasks are all resume targets |
| 3 | Shorten resume with "login success = verification complete" | Login is a prerequisite. Run each verification item (countdown, permissions, etc.) individually |
| 4 | After completing 1 Resume item → switch to AskUserQuestion "what's next?" | Complete all Resume items sequentially. Completing 1 is not a switch point — start the next item immediately |
| 5 | Sub-task completed → "this task is done, let's take a breath" | After sub-task completes, immediately move to the next item of the Resume task. AskUserQuestion only after all Resume items complete |
fix-2 subject — it contains the full list from the initial request to the immediately preceding actionStep 3 constraints:
git checkout -- ., git reset --hard, rm -rf, etc. must not be executed without approval even under the pretext of "restoring original work"Anti-patterns:
Forbid verification scope reduction (HARD STOP — 2nd recurrence prevention):
Do not use a different medium than what the user reported as a detour. Reproduce via the "verification medium" specified in fix Step 3-0.
| # | Don't | Do |
|---|---|---|
| 1 | User reports "/api/X error" → substitute verification with login success / other APIs working | Directly call the user-seen /api/X via curl/Playwright → verify response status/body |
| 2 | User reports "permission error on screen Y" → after DB ALTER, only confirm admin login | Enter the user-seen screen via admin session → reproduce the same interaction → confirm whether the permission error recurs |
| 3 | One step (login) passes → assume subsequent steps (permission check / page entry / API call) are OK | Run each subsequent step individually for every step in the user-reported medium |
| 4 | Assume "logs are clean → normal" | Logs clean + the user-medium reproduction response both required |
Self-check (every time before reporting verification complete):
Violation case (2026-05-09): In fix #93, while diagnosing "/api/system-log?limit=30 error", only admin login + integrated dashboard load were checked and reported as "ALTER verification complete". In reality, calling the system-log API itself reproduced the permission error → user re-pointed it out, starting fix #102.
Step 3 mandatory self-questions (MANDATORY before marking fix-2 complete):
⚠️ Chained /fix Resume integrated execution gate (HARD STOP):
If /fix has been invoked 2+ times in this session, before marking fix-* tasks deleted in Step 4, collect all 🔄 Resume tasks in TaskList and verify outstanding work.
| # | Don't | Do |
|---|---|---|
| 1 | completed→deleted only the current fix's fix-2 | Collect every task in TaskList containing the 🔄 Resume keyword |
| 2 | Ignore and delete a prior fix's Resume that is in_progress | Split prior Resume's outstanding work into separate tasks before deleting |
| 3 | Mark each fix complete independently | Integrate and clean up outstanding work from all Resumes before bulk-deleting |
Procedure:
TaskList → collect every task containing 🔄 Resume or ResumeFix complete:
- Root cause: {what was missing}
- Improvement: {which file was modified and how}
- Current fix: {result of fixing the current issue}
*Outstanding-work separation guard (HARD STOP — required before deleting fix- tasks)**:
If fix-2 (Resume Original Work) contains outstanding work, separate by medium per status before deleting fix-* tasks:
| Status | Example | Medium (TaskList vs checklist) |
|---|---|---|
| Hold (user decision) | "Track B is next session", "Playwright on hold" | TaskList: when actionable |
| Partial completion | Track A done, Track B not run | TaskList: separate task for Track B |
| Awaiting follow-up verification | Awaiting CI pass, awaiting merge review | TaskList: can trigger verification |
| Awaiting external response (BLOCKED) | Awaiting owner reply, external API lock, awaiting permission grant | Register in fix_plan.md hold section (no task) |
| Cannot proceed autonomously | Items that cannot move one step without user decision/external action | fix_plan.md hold section |
Why is BLOCKED forbidden as a task?
| # | Don't | Do |
|---|---|---|
| 1 | Register external-wait items in both a separate task and fix_plan | Register only in fix_plan.md hold section. No task creation |
| 2 | Create a task with subject "[BLOCKED] awaiting reply on xxx" | Use fix_plan.md ## Hold section in the form - [ ] [BLOCKED] xxx (... awaiting reply, trigger: ...) |
| 3 | "Register as task so the user doesn't forget" thinking | fix_plan.md is reloaded at each session start, so it won't be forgotten. The checklist is sufficient |
| 4 | Keep both checklist and task entries to "strengthen safety" | Duplicate media = mismatch risk. Unify to a single medium |
Violation patterns:
Correct flow (PR #299 example):
After reporting + outstanding-work separation verified, delete all fix-* TODO items created in Step 0 — fix TODOs are temporary session-level tracking only; outstanding work is preserved in separate tasks while only fix-* are cleaned up.