← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

match() Default Arm vs No Default

php PHP 8.0+ Intermediate
debt(d3/e1/b3/t5)
d3 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'default linter catches the common case' (d3). PHPStan and Psalm (cited in detection_hints.tools) can detect missing match arms, especially when used with enums or union types. These are commonly configured static analysis tools that catch the pattern automatically.

e1 Effort Remediation debt — work required to fix once spotted

Closest to 'one-line patch or single-call swap' (e1). The quick_fix explicitly states: 'Always add a default arm to match()' — this is literally adding one line like 'default => throw new \UnexpectedValueException()' to the existing match expression.

b3 Burden Structural debt — long-term weight of choosing wrong

Closest to 'localised tax' (b3). The choice affects individual match expressions within specific functions. While applies_to shows it's relevant across web/cli/queue contexts, each match() is isolated and doesn't impose structural weight on the broader codebase architecture.

t5 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'notable trap (a documented gotcha most devs eventually learn)' (t5). The misconception field directly states developers assume 'match() without default silently returns null like switch' when it actually throws UnhandledMatchError. This contradicts expectations from switch behavior, but it's a well-documented PHP 8 gotcha that developers learn through experience.

About DEBT scoring →

TL;DR

match() without a default arm throws UnhandledMatchError if no arm matches — unlike switch, which silently falls through.

Explanation

match() is exhaustive by design. When no arm matches and there is no default, PHP throws \UnhandledMatchError (extends \Error). This is intentional — match() forces you to handle all cases explicitly. Add default => throw new \InvalidArgumentException() for expected-but-invalid values, or default => null when missing is acceptable. Use with enums: PHP will warn if match on a backed enum is non-exhaustive in a future version. Contrast with switch: switch falls through silently, match throws.

Common Misconception

match() without default silently returns null like switch — it throws UnhandledMatchError, making it strictly safer.

Why It Matters

UnhandledMatchError surfaces unhandled cases immediately instead of silently producing null or wrong values as switch would.

Common Mistakes

  • Forgetting default arm when new enum values are added.
  • Using match() for nullable values without handling null explicitly.
  • Catching generic \Error instead of \UnhandledMatchError.

Code Examples

✗ Vulnerable
$status = match($code) {
    200 => 'ok',
    404 => 'not found',
    // No default — code 500 throws UnhandledMatchError
};
✓ Fixed
$status = match($code) {
    200 => 'ok',
    404 => 'not found',
    500, 503 => 'server error',
    default => throw new \InvalidArgumentException("Unknown HTTP code: $code"),
};

Added 22 Mar 2026
Views 23
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 0 pings F 0 pings S 1 ping S 0 pings M 0 pings T 1 ping W 0 pings T 0 pings F 2 pings S 1 ping S 0 pings M 0 pings T 0 pings W 1 ping T 0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 1 ping S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F
No pings yet today
No pings yesterday
Amazonbot 9 Unknown AI 3 Google 3 Perplexity 2 ChatGPT 1 Meta AI 1 SEMrush 1 Ahrefs 1
crawler 18 crawler_json 2 pre-tracking 1
DEV INTEL Tools & Severity
🟡 Medium ⚙ Fix effort: Low
⚡ Quick Fix
Always add a default arm to match(). Use default => throw new \UnexpectedValueException() to make unhandled cases explicit errors rather than silent failures.
📦 Applies To
PHP 8.0+ web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
match\(
Auto-detectable: ✓ Yes phpstan psalm
⚠ Related Problems
🤖 AI Agent
Confidence: High False Positives: Medium ✓ Auto-fixable Fix: Low Context: Function Tests: Update

✓ schema.org compliant