Footgun
A feature, tool or API that makes it easy to shoot yourself in the foot: the obvious use works most of the time, then does something harmful that nobody notices right away.
Also known as: Foot-Gun, Shooting Yourself in the Foot, Foot Gun
Category: Software Development
Tags: software-design, software-development, api-design, developer-experience, error-prevention, anti-patterns
Explanation
The word comes from the old expression "to shoot yourself in the foot". Programmers turned it into a noun. A footgun is a feature that seems fine, gets used the obvious way, and then hurts the person using it. Usually at the worst possible moment.
Footguns are the opposite of a Pit of Success. Instead of falling into good results, you fall into bugs, data loss or security holes, often without noticing until much later.
**Classic examples**:
- **`rm -rf "$DIR/"`** in a shell script: if `$DIR` happens to be empty, you just asked to delete `/`
- **The YAML "Norway problem"**: in YAML 1.1, the country code `NO` gets parsed as the boolean `false`
- **JavaScript's `==`**: `"0" == false` is `true`, and so is `[] == false`
- **Zero-based months in JavaScript dates**: `new Date(2026, 1, 1)` is February, not January
- **`git push --force`** on a shared branch: it silently erases your colleagues' commits
- **C's `gets()`**: it has no way to limit input size, so every use is a buffer overflow waiting to happen (it was finally removed in C11)
- **Floating-point money**: `0.1 + 0.2` is not `0.3`, and someone's invoice will show it
**What makes something a footgun?**
- The dangerous behavior is the DEFAULT, or the shortest thing to type
- It works in the common case, so nobody notices the problem during testing
- The failure is silent, delayed or far away from the cause
- Avoiding it depends on knowledge the user is unlikely to have
**How to remove footguns**:
1. **Delete them**: Deprecate and remove the dangerous API when you can (like `gets()`)
2. **Make the safe version the easy version**: `git push --force-with-lease` exists for exactly this reason
3. **Make the dangerous version loud**: React named its raw HTML API `dangerouslySetInnerHTML`. Nobody types that by accident
4. **Fail early**: Turn silent misbehavior into a clear error (e.g., `set -u` in Bash makes unset variables fail)
5. **Add guardrails**: Linters, type checks and confirmation prompts catch what the design couldn't prevent
Keep in mind that a footgun is a design problem. Don Norman makes the same point in The Design of Everyday Things: when many people make the same mistake, look at the design before blaming the people.
Related Concepts
← Back to all concepts