# Apex Enum Patterns

> Use Apex enums for closed-set dispatch and routing, with safe valueOf conversion, exhaustiveness checks, and managed-package considerations.

- Skill: `pranavnagrecha/apex-enum-patterns` (Agent Skill, multi-file: 7 files)
- Install (CLI): `npx skillmds@latest add pranavnagrecha/apex-enum-patterns`
- Raw SKILL.md: https://api.skillmd.com/api/skills/pranavnagrecha/apex-enum-patterns/raw
- Safety review: PASS (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools, API Design
- Tags: Apex, Custom Metadata, Enums, Managed Packages, Salesforce, Switch, Valueof
- Author: PranavNagrecha (https://skillmd.com/u/pranavnagrecha)
- Updated: 2026-08-22
- Page: https://skillmd.com/skills/pranavnagrecha/apex-enum-patterns

---


# Apex Enum Patterns

Apex enums are simpler than Java enums — no constructors, no
methods on enum constants, no per-value data — but they still beat
unstructured strings for state-machine dispatch, message routing,
and any "one of N exhaustive options" code path.

The mistakes follow a predictable pattern: people serialize enum
values into Custom Metadata or a Long Text field, the picklist
gets renamed, and `Enum.valueOf(String)` starts throwing
`System.NoSuchElementException` in production. Or someone adds a
new enum value and the `switch on` doesn't have a branch — Apex
falls through silently because there's no compiler exhaustiveness
check.

This skill covers the patterns that make enums useful in Apex
without the foot-gun.

## Recommended Workflow

1. **Decide if an enum is the right shape.** If you have <2 values
   or values change at runtime, use a Boolean or a Custom
   Metadata-driven string. Enums are for closed sets.
2. **Name the enum after intent, not type.** `RenewalAction`
   beats `EnumType1`.
3. **Use `switch on <Enum>` with a `when else` branch** that throws
   a clear exception. This is the only way to surface a missed
   case at runtime when the enum gains a new value.
4. **Wrap `Enum.valueOf(String)` in a safe converter** that returns
   a default or throws a typed exception with the offending input
   in the message.
5. **Document `global` vs `public` in managed packages.** Once
   shipped, removing or renaming a `global` enum value is a
   breaking change.
6. **Write a test that asserts the enum's `values()` matches the
   expected set.** This is the cheapest exhaustiveness check Apex
   gives you.

## When To Reach For An Enum

The right places: trigger-handler dispatch keys, message-routing
discriminators, log-level enums, status machines that the app
itself owns end-to-end. Anywhere the set of values is a property
of the code, not the data, an enum is the cheaper, safer choice.

The wrong places: anything an admin should be able to add to. If
adding a new "approval reason" should not require a deployment,
do not put it in an enum. The enum becomes a maintenance ratchet
that pulls every dispatcher into the release pipeline.

## What This Skill Does Not Cover

- **Picklist-field design** — see `admin/picklist-design`.
- **Custom Metadata as configuration store** — see `apex/custom-metadata-types`.
- **State machines with side effects** — see `architect/state-machine-patterns`.

