Agent skill
ecto-constraint-debug
Debug Ecto constraint violations - trace triggers, check migrations, find duplicate data. Use when seeing unique_constraint, foreign_key_constraint, or check_constraint errors.
Install this agent skill to your Project
npx add-skill https://github.com/oliver-kriska/claude-elixir-phoenix/tree/main/plugins/elixir-phoenix/skills/ecto-constraint-debug
SKILL.md
Ecto Constraint Debugging
Systematic approach to diagnosing constraint violations. Load when you see Ecto.ConstraintError, unique_constraint, foreign_key_constraint, or constraint-related changeset errors.
Iron Laws
- READ THE CONSTRAINT NAME — The constraint name (e.g.,
links_url_index) tells you exactly which index/constraint failed. Parse it from the error message first - CHECK MIGRATION BEFORE CODE — Verify the constraint definition in
priv/repo/migrations/matches what the schema expects - TRACE ALL INSERT PATHS — Find every code path that inserts into the constrained table. The bug is often in a path you didn't consider
- RACE CONDITION UNTIL PROVEN OTHERWISE — If validation passes but constraint fails, assume concurrent inserts until you prove a single-request cause
Step-by-Step Debugging
Step 1: Parse the Error
Extract from the error message:
- Constraint name (e.g.,
users_email_index) - Table name (e.g.,
users) - Operation (insert, update, or delete)
- Conflicting values (if available in logs)
Step 2: Find the Migration
Use Grep to search for the constraint name in priv/repo/migrations/. Also check for create unique_index, create index, add constraint.
Verify: Does the migration constraint match the schema's unique_constraint/3 or foreign_key_constraint/3 call?
Step 3: Find the Schema
Use Grep to find constraint handling in changesets (unique_constraint, foreign_key_constraint, check_constraint) in lib/.
Step 4: Trace Insert Paths
Find ALL callers that insert/update this schema:
Use Grep to find all insert/update paths (Repo.insert, Repo.update, Repo.insert_all, cast_assoc) in lib/.
Step 5: Identify the Cause
| Symptom | Likely Cause | Fix Pattern |
|---|---|---|
| Same user triggers twice | Race condition (double-click, retry) | Upsert with on_conflict |
| Multiple parents share child | cast_assoc doesn't dedup across changesets |
Dedup before building changesets |
| Concurrent API requests | Missing transaction isolation | Wrap in Repo.transaction or use upsert |
| Migration added constraint to existing data | Data violates new constraint | Backfill or clean data first |
Step 6: Apply Fix
See ${CLAUDE_SKILL_DIR}/references/constraint-patterns.md for detailed fix patterns.
Quick Fixes by Constraint Type
Unique violation → Upsert: Repo.insert(changeset, on_conflict: :replace_all, conflict_target: [:field])
Foreign key violation → Check: Does the referenced record exist? Was it deleted concurrently?
Check constraint → Validate: Does the value satisfy the constraint condition?
References
${CLAUDE_SKILL_DIR}/references/constraint-patterns.md- Detailed patterns for each constraint type
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
lab:autoresearch
Self-improving loop for plugin skills. Reads program.md, proposes one mutation per iteration, evaluates against deterministic scorer, keeps improvements via git, reverts failures. Targets weakest skill+dimension. Use with /loop for overnight runs.
promote
Generate X/Twitter release promotion posts with ASCII tables and CodeSnap rendering. Use when writing release posts, promotion tweets, plugin announcements, or preparing social media content for new versions.
skill-monitor
Analyze skill effectiveness across sessions. Computes per-skill metrics (action rate, friction, outcomes), identifies degrading skills, and generates improvement recommendations. Requires session-scan data in metrics.jsonl.
session-trends
Analyze trends across session metrics. Computes windowed aggregates, deltas, and compares against MEMORY.md findings. Use periodically for progress tracking.
cc-changelog
CONTRIBUTOR TOOL - Track CC changelog, extract new versions since last check, analyze impact on plugin (breaking changes, opportunities, deprecations). Run periodically or before releases. NOT part of the distributed plugin.
session-scan
Compute metrics for Claude Code sessions. Discovers via ccrider, filters trivial, computes friction/opportunity/fingerprint scores. Use for broad session triage.
Didn't find tool you were looking for?