Learn on Failure
Captures hard-won lessons into per-project memory so the same detour isn’t repeated. It fires automatically — without being asked — whenever a task took more than one fix cycle to resolve (a test that failed and needed a second attempt, a compile error, an API that behaved unexpectedly, an assumption that proved wrong), synthesizing the root cause and the correct approach into the project’s memory files. It also records anything the user explicitly asks to remember.
Trigger it
/learn-on-failure:learn-on-failure testing "BCrypt accepts $2a$ but not $2y$ hashes"
Mostly it fires automatically after any multi-cycle fix — you don’t invoke it. To save something on demand, just say: "remember this: …" or "save this learning".
When to use it
-
Automatically after any multi-cycle resolution — a second attempt was needed to get something working
-
A non-obvious library behavior, API quirk, or version/compatibility constraint surfaced mid-task
-
The user explicitly says "remember this" / "save this learning"
-
Not for routine, single-pass work that succeeded first time
What it does
Locates project memory
Writes to Claude Code’s per-project memory at ~/.claude/projects/<project-slug>/memory/ — using the path supplied in the session’s memory context, never a hardcoded one. MEMORY.md is the index; topic files (e.g. dependencies.md, testing.md, debugging.md) hold detailed notes. Creates them if absent.
Synthesizes the learning
On an automatic trigger it derives, from the conversation: the root cause of the extra cycle(s), the failed assumption, the correct approach, and what to check first next time. On a user trigger it records exactly what was stated.
Writes it concisely
Short insights go into a MEMORY.md section (kept under 200 lines); detailed learnings go into a topic file with a one-line index reference. Entries are bullet points that lead with what to do / check and follow with why, superseding stale notes rather than duplicating them. Confirms in one line where it saved.
Fail-streak nudge (1.2.0)
The skill fires after a multi-cycle fix. The cycles themselves often look like this: the same command, run again, failing again. From 1.2.0 the plugin ships a small hook that notices.
When the same Bash command fails three times in a row, the hook adds one line to Claude’s context:
The same command has now failed 3 times in a row: npm test. Running it again is not converging. Stop and change approach: read the error text, check the assumption the command rests on, or take a different route. When this is resolved it was a multi-cycle fix — save what the wrong assumption was with the learn-on-failure skill.
-
Any passing command ends the streak. A different failing command starts its own count.
-
It speaks at three, then stays quiet until six, then nine — a reminder, not a nag.
-
Runs that differ only in whitespace are the same command. A command you interrupted is your decision, not a failure.
-
It is context only. It never approves, blocks or changes a command.
-
The count lives in a small per-session file under
~/.claude/learn-on-failure/streaks, readable only by you and pruned after a week; nothing is written to the plugin or the repo.
It reads the failure from the hook event itself (PostToolUseFailure), not by parsing output, and was checked in a real session: the note reached the model on the third failure. If another plugin rewrites commands with a launcher prefix, the prefix is stripped so the note quotes what you actually ran.
Claude Code only: the hook is not wired for Codex.
What’s new in 1.1.0
-
Every fire appends one line to the consuming repo’s
.claude/learn-on-failure/log.md— a prose-triggered skill that never fires looks identical to a repo with nothing to learn, and the log is what makes under-firing visible. -
Routing: repo-durable, team-relevant learnings belong in evolving-claude-md's Decisions & Learnings log, not user memory; this skill is the write path for the personal remainder. evolving-claude-md’s capture prompts route here for that half.
Notes
-
Saves root causes, non-obvious API quirks, version constraints (e.g. BCrypt
$2y$vs$2a$), architectural decisions, and stated user preferences. -
Does not save routine first-pass outcomes, transient task state, anything already in
CLAUDE.md, or unverified guesses.
Claude Code vs Codex
Tier 3 — lifecycle hooks on both clients.
| Claude Code | Codex | |
|---|---|---|
Where learnings go |
Claude’s native project memory, which Claude loads automatically. |
|
Hooks |
None — Claude already loads its memory. |
A SessionStart hook loads the index. With a skill-only install, read it explicitly. |
The difference that matters: This is the one plugin with a Codex hook and no Claude hook: Codex has no auto-loaded project memory to lean on, so the plugin supplies the loader.
Install, hook trust and verified limits: Codex compatibility.