While working with Claude Code, Sonnet 5.x diagnosed some C# I inherited as containing a "footgun." I had never heard the term footgun before. I mean, the most lethal footwork I'd seen was Rosa Klebb’s poison-tipped shoe blades immortalized in 'From Russia with Love.'
In modern computer science nomenclature, a footgun is a design that is technically valid but makes it unnecessarily easy for a developer to make a mistake.
A close-to-real-world example of this is as follows:
ILogger dataPlaneLogger =
_architecturalPlanesFactory.GetDataPlaneLogger();
The factory method indicates that the logger is Data Plane specific. But the returned type is ILogger, which for all intents and purposes could be anything (log to a UDP port, log to Cloudflare R2 blob store, log to App Insights).
The factory makes the ambiguity explicit:
ILogger GetDataPlaneLogger();
ILogger GetControlPlaneLogger();
After that assignment, the type system no longer knows that this is the Data Plane logger. A variable named dataPlaneLogger cannot enforce that it was returned by method GetDataPlaneLogger. It is just another ILogger.
This is exacerbated by dependency injection. Consider a .NET 10 / C# class that requires a logging sink for the Control Plane and a logger sink for the Data Plane:
public class PlaneService(
ILogger controlPlaneLogger,
ILogger dataPlaneLogger)
{
}
The parameter names communicate intent to a human, but dependency injection resolves both services as the same type: ILogger. The primary constructor has two parameters of the same type, so there is no type-level distinction between logging to the Control Plane and logging to the Data Plane.
This ambiguity is an example of a footgun.