# Elixir Antipatterns

Core catalog of 8 critical Elixir/Phoenix anti-patterns covering error handling...

- Repository: https://github.com/Gentleman-Programming/Gentleman-Skills (661 stars)
- Category: Testing
- License: MIT
- Last updated: 2026-03-28
- Runs scripts: no, instructions only

## Install

Claude Code: `npx skills add Gentleman-Programming/Gentleman-Skills --skill elixir-antipatterns -g -a claude-code -y`
Codex: `npx skills add Gentleman-Programming/Gentleman-Skills --skill elixir-antipatterns -g -a codex -y`
Cursor: `npx skills add Gentleman-Programming/Gentleman-Skills --skill elixir-antipatterns -g -a cursor -y`
Gemini CLI: `npx skills add Gentleman-Programming/Gentleman-Skills --skill elixir-antipatterns -g -a gemini-cli -y`

## Description

Core catalog of 8 critical Elixir/Phoenix anti-patterns covering error handling, separation of concerns, Ecto queries, and testing. Trigger: During Elixir code review, refactoring sessions, or when writing Phoenix/Ecto code.

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# Elixir Anti-Patterns

Critical anti-patterns that compromise robustness and maintainability in Elixir/Phoenix applications.

> **Complement with**: `mix format` and `Credo` for style enforcement  
> **Extended reference**: See `EXTENDED.md` for 40+ patterns and deep-dive examples

---

## When to Use

**Topics:** Error handling (3 patterns) • Architecture (2 patterns) • Performance (2 patterns) • Testing (1 pattern)

Load this skill when:
- Writing Elixir modules and functions
- Working with Phoenix Framework (Controllers, LiveView)
- Building Ecto schemas and database queries
- Implementing BEAM concurrency (Task, GenServer)
- Handling errors with tagged tuples
- Writing tests with ExUnit

---

## Critical Patterns

Quick reference to the 8 core patterns this skill enforces:

1. **Tagged Tuples**: Return `{:ok, value} | {:error, reason}` instead of `nil` or exceptions
2. **Explicit @spec**: Document error cases in function signatures
3. **Context Separation**: Business logic in contexts, not LiveView
4. **Preload Associations**: Use `Repo.preload/2` to avoid N+1 queries
5. **with Arrow Binding**: Use `<-` for all failable operations in `with`
6. **Database Indexes**: Index frequently queried columns
7. **Test Assertions**: Every test must assert expected behavior
8. **Cohesive Functions**: Group `with` chains >4 steps into functions

> See `## Anti-Patterns` section below for detailed ❌ BAD / ✅ CORRECT code examples.

---

## Code Examples

### Example 1: Error Handling with Tagged Tuples

```elixir
# ✅ CORRECT - Errors as values, explicit in @spec
defmodule UserService do
  @spec fetch_user(String.t()) :: {:ok, User.t()} | {:error, :not_found}
  def fetch_user(id) do
    case Repo.get(User, id) do
      nil -> {:error, :not_found}
      user -> {:ok, user}
    end
  end
end

# ❌ BAD - Exceptions for business errors
def fetch_user(id) do
  Repo.get(User, id) || raise "User not found"
end
```

### Example 2: Phoenix LiveView with Context Separation

The rest: https://github.com/Gentleman-Programming/Gentleman-Skills/blob/HEAD/community/elixir-antipatterns/SKILL.md
