phx-investigate
Investigate Elixir/Phoenix bugs root-cause first. Reproduce failures,
Install
npx skills add https://github.com/oliver-kriska/claude-elixir-phoenix/tree/main/targets/amp/skills/phx-investigate
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install oliver-kriska-claude-elixir-phoenix@llmmart
git clone https://github.com/oliver-kriska/claude-elixir-phoenix.git
The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole oliver-kriska/claude-elixir-phoenix collection as a plugin from our marketplace. Git is the plain clone.
Skill manifest
Investigate Bug
Investigate Elixir/Phoenix bugs root-cause first. Reproduce or establish the failing behavior before recommending a fix, and cite concrete paths and lines.
Usage
phx-investigate Users can't log in after password reset
phx-investigate FunctionClauseError in UserController.show
phx-investigate Complex auth bug --parallel
Treat the text after the skill name as the bug description. --parallel asks
for independent investigation tracks when native Amp subagent tooling is
available; it is an optimization, never a requirement.
Iron Laws
- Read the error literally first — extract the exception, message, failing assertion, and first relevant application frame before theorizing.
- Check the obvious before going deep — compile errors, missing migrations, atom/string mismatches, nil values, stale servers, and changeset errors explain many failures.
- Reproduce before proposing a fix — run the smallest relevant test or controlled command and record its output. If reproduction is impossible, state exactly what evidence establishes the failure instead.
- Confirm the root cause with evidence — distinguish the observed failure, the causal code path, and the proposed correction.
- Do not edit while investigating unless the user asks for a fix — the investigation result is evidence and a recommendation, not an implicit patch.
Workflow
1. Consult Existing Evidence
Search .claude/solutions/, recent diffs, tests, logs, and the literal error.
Do not block if .claude/solutions/ does not exist.
2. Capture Runtime Context When Available
Tidewave is optional. If its tools are configured, use them for logs, source
locations, safe queries, or hypothesis checks. Otherwise use repository files,
mix commands, and local logs. Never fail or ask the user to install Tidewave
merely to continue an investigation.
3. Run Sanity Checks
Choose focused checks that fit the report, such as:
mix compile --warnings-as-errors
mix test test/path_test.exs --trace
Do not run migrations or other state-changing commands unless they are necessary, safe for the fixture, and authorized by the user.
4. Reproduce Before Fixing
Capture the exact command, failure, and relevant output. Read
references/error-patterns.md, then inspect only the code needed to trace the
failure from entry point to cause.
5. Check the Obvious
Check saved files, atom/string keys, preload state, pattern matches, nil values,
return values, server restarts, and changeset errors. For silent LiveView form
failures, inspect {:error, changeset} and rendered validation errors before JS.
6. Trace and Test the Hypothesis
Use targeted searches, source reads, tests, or non-mutating diagnostics. Only add
temporary source diagnostics if the user explicitly authorizes edits, and remove
them before reporting. Cite path:line evidence for both the failing behavior
and the causal code.
If native Amp subagents are available and the bug genuinely spans independent areas, delegate read-only tracks by concern. Otherwise perform the same tracks sequentially in this session. Do not require named custom agents.
7. Report
Use references/investigation-template.md. Include:
- reproduction or evidence establishing the failure;
- root cause, not merely the symptom;
- relevant paths and lines;
- confidence and any unverified assumptions;
- the smallest safe fix or next diagnostic step.
Route follow-up work with phx-quick, phx-plan, or phx-compound when
appropriate. Do not invoke another skill unless the user asks you to continue.
References
references/error-patterns.md— common errors and checklistreferences/investigation-template.md— output formatreferences/debug-commands.md— debug commands and common fixes
Amp native parallel investigation
For a non-trivial failure with independent reproduction, root-cause, impact,
and fix-strategy questions, call elixir_phoenix_parallel_investigate once.
Its four local child threads are enforced read-only (Read and finder only).
Reconcile their output in this parent thread and verify every claimed evidence
path before editing. If the tool is unavailable or a child fails, run only the
missing track sequentially. Simple failures should stay sequential.
Files (claude-elixir-phoenix)
-
references
-
debug-commands.md 2 KB
# Quick Debug Commands & Common Fixes ## Quick Debug Commands Common debug commands: - Clean rebuild: `rm -rf _build deps && mix deps.get && mix compile` - Check module exports: `mix run -e "IO.inspect MyModule.__info__(:functions)"` - Interactive debugging: `iex -S mix phx.server` (then `recompile()`) - Run single test with output: `mix test test/file_test.exs:42 --trace` ## Common Fixes ### String vs Atom Keys ```elixir # External data (JSON, params) = strings params["key"] # Internal data = atoms struct.field map.key ``` ### Missing Preload ```elixir # Before user = Repo.get(User, id) user.posts # BOOM # After user = Repo.get(User, id) |> Repo.preload(:posts) ``` ### Nil Propagation ```elixir # Before user.profile.name # Crashes if profile nil # After case user.profile do nil -> nil profile -> profile.name end # Or use get_in/2 ``` ## Telemetry-Based Debugging When Tidewave is unavailable, use telemetry to diagnose performance and behavior issues: ```elixir # Attach a temporary handler to see all Ecto queries :telemetry.attach( "debug-queries", [:my_app, :repo, :query], fn _event, measurements, metadata, _config -> IO.puts("Query: #{metadata.query}") IO.puts(" Time: #{measurements.total_time / 1_000_000}ms") end, nil ) # Detach when done: :telemetry.detach("debug-queries") ``` ### Common Telemetry Events to Attach | Event | What It Shows | |-------|---------------| | `[:my_app, :repo, :query]` | All Ecto queries with timing | | `[:phoenix, :endpoint, :stop]` | Request duration | | `[:phoenix, :router_dispatch, :stop]` | Per-route timing | | `[:oban, :job, :stop]` | Oban job execution time | | `[:oban, :job, :exception]` | Oban job failures | ### LiveDashboard in Dev Add to router for real-time metrics visualization: ```elixir if Mix.env() in [:dev, :test] do import Phoenix.LiveDashboard.Router scope "/" do pipe_through :browser live_dashboard "/dashboard", metrics: MyAppWeb.Telemetry end end ``` -
error-patterns.md 1.4 KB
# Error Patterns - Read Error LITERALLY ## Common Elixir/Phoenix Errors | Error | Literal Meaning | Check | |-------|-----------------|-------| | `UndefinedFunctionError: MyMod.func/2` | Function doesn't exist with that arity | Is it `func/1` not `func/2`? | | `KeyError: key :name not found` | Map doesn't have `:name` key | String key `"name"` instead? | | `FunctionClauseError` | No pattern matched | `IO.inspect` the actual data | | `(Ecto.NoResultsError)` | Query returned nil | Data doesn't exist in DB | | `(Protocol.UndefinedError)` | Protocol not implemented | Wrong data type passed | ## Ralph Wiggum Checklist Check systematically, or delegate to a generic read-only subagent if native Amp subagent tooling is available: 1. Is the file saved? 2. Atom vs string key mismatch? 3. Is data preloaded? 4. Is the pattern match correct? 5. Is nil being passed somewhere? 6. Is the return value correct (conn/socket)? 7. Did you restart the server? ## Temporary Diagnostics Only when the user explicitly authorizes temporary source edits, add and later remove diagnostics such as: ```elixir # Add to suspected location |> IO.inspect(label: "DEBUG: data after transform") ``` ## When Stuck 1. Inspect values through failing test output or an available safe runtime eval 2. Run a focused IEx expression without modifying source files 3. Trace reachability through existing logs or tests; source edits require approval 4. Compare the working and broken paths -
investigation-template.md 998 B
# Investigation Output Template Return this structure in the current session; do not write a report file unless the user explicitly asks for one: ````markdown # Bug Investigation: <bug description> ## Error ``` {exact error message} ``` ## Reproduction ```bash {command to reproduce} ``` ## Ralph Wiggum Checklist - [x] File saved? YES - [x] Compiled? YES - [ ] Correct key type? **NO - FOUND IT** - [ ] Data exists? Not checked ## Root Cause **What's wrong**: Using string key "user_id" but map has atom :user_id **Where**: lib/my_app_web/controllers/user_controller.ex:45 **Why missed**: External API returns string keys, internal code uses atoms ## Fix ```elixir # Before def show(conn, %{"user_id" => id}) do user = Accounts.get_user(params["user_id"]) # params has string keys! # After def show(conn, %{"user_id" => id}) do user = Accounts.get_user(id) # Already extracted ``` ## Prevention - Add test with external API mock - Add typespec to catch at compile time ````
-
-
SKILL.md 4.4 KB
--- name: phx-investigate description: Investigate Elixir/Phoenix bugs root-cause first. Reproduce failures, cite evidence, and use optional Amp subagents only when useful. --- # Investigate Bug Investigate Elixir/Phoenix bugs root-cause first. Reproduce or establish the failing behavior before recommending a fix, and cite concrete paths and lines. ## Usage ```text phx-investigate Users can't log in after password reset phx-investigate FunctionClauseError in UserController.show phx-investigate Complex auth bug --parallel ``` Treat the text after the skill name as the bug description. `--parallel` asks for independent investigation tracks when native Amp subagent tooling is available; it is an optimization, never a requirement. ## Iron Laws 1. **Read the error literally first** — extract the exception, message, failing assertion, and first relevant application frame before theorizing. 2. **Check the obvious before going deep** — compile errors, missing migrations, atom/string mismatches, nil values, stale servers, and changeset errors explain many failures. 3. **Reproduce before proposing a fix** — run the smallest relevant test or controlled command and record its output. If reproduction is impossible, state exactly what evidence establishes the failure instead. 4. **Confirm the root cause with evidence** — distinguish the observed failure, the causal code path, and the proposed correction. 5. **Do not edit while investigating unless the user asks for a fix** — the investigation result is evidence and a recommendation, not an implicit patch. ## Workflow ### 1. Consult Existing Evidence Search `.claude/solutions/`, recent diffs, tests, logs, and the literal error. Do not block if `.claude/solutions/` does not exist. ### 2. Capture Runtime Context When Available Tidewave is optional. If its tools are configured, use them for logs, source locations, safe queries, or hypothesis checks. Otherwise use repository files, `mix` commands, and local logs. Never fail or ask the user to install Tidewave merely to continue an investigation. ### 3. Run Sanity Checks Choose focused checks that fit the report, such as: ```bash mix compile --warnings-as-errors mix test test/path_test.exs --trace ``` Do not run migrations or other state-changing commands unless they are necessary, safe for the fixture, and authorized by the user. ### 4. Reproduce Before Fixing Capture the exact command, failure, and relevant output. Read `references/error-patterns.md`, then inspect only the code needed to trace the failure from entry point to cause. ### 5. Check the Obvious Check saved files, atom/string keys, preload state, pattern matches, nil values, return values, server restarts, and changeset errors. For silent LiveView form failures, inspect `{:error, changeset}` and rendered validation errors before JS. ### 6. Trace and Test the Hypothesis Use targeted searches, source reads, tests, or non-mutating diagnostics. Only add temporary source diagnostics if the user explicitly authorizes edits, and remove them before reporting. Cite `path:line` evidence for both the failing behavior and the causal code. If native Amp subagents are available and the bug genuinely spans independent areas, delegate read-only tracks by concern. Otherwise perform the same tracks sequentially in this session. Do not require named custom agents. ### 7. Report Use `references/investigation-template.md`. Include: - reproduction or evidence establishing the failure; - root cause, not merely the symptom; - relevant paths and lines; - confidence and any unverified assumptions; - the smallest safe fix or next diagnostic step. Route follow-up work with `phx-quick`, `phx-plan`, or `phx-compound` when appropriate. Do not invoke another skill unless the user asks you to continue. ## References - `references/error-patterns.md` — common errors and checklist - `references/investigation-template.md` — output format - `references/debug-commands.md` — debug commands and common fixes ## Amp native parallel investigation For a non-trivial failure with independent reproduction, root-cause, impact, and fix-strategy questions, call `elixir_phoenix_parallel_investigate` once. Its four local child threads are enforced read-only (`Read` and `finder` only). Reconcile their output in this parent thread and verify every claimed evidence path before editing. If the tool is unavailable or a child fails, run only the missing track sequentially. Simple failures should stay sequential.
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.