Join our Newsletter — 33% off our NHI Course
Home› Glossary› Foundations & NHI Taxonomy› Mutable Default Argument
Foundations & NHI Taxonomy

Mutable Default Argument

← Back to Glossary
By NHI Mgmt Group Updated October 31, 2026 Domain: Foundations & NHI Taxonomy

A mutable default argument is a function parameter whose default value is a list, dictionary, or other object that can change. Python evaluates the default once when the function is defined, so later calls can reuse the same object and accidentally carry state across invocations.

What Makes a Mutable Default Argument Surprising

A mutable default argument is not evaluated on each call. In Python, the default object is created once when the function is defined, so the same list, dictionary, or custom object can be reused across invocations. That makes the function behave differently from what many developers expect when they assume each call starts from a clean slate.

The key surprise is not that the object is mutable, but that the default lives at function-definition time rather than call time. That means state can accumulate invisibly, and a function that looks stateless can quietly become stateful.

How the Shared State Appears

The problem usually shows up when a function mutates the default value in place. If the default is appended to, extended, updated, or otherwise changed, those changes persist for the next call because the same object is reused. The result can be repeated items, stale values, or behavior that depends on call order.

This is especially confusing in code reviews because the function signature can look harmless. A default like [] or {} reads as if it were only a convenience value, but in practice it can become a hidden cache, accumulator, or scratchpad.

Why It Matters in Real Programs

Mutable defaults can create correctness bugs that are hard to trace because the state lives outside the function body in an unusual place. A caller may see a result that reflects prior invocations, not just the current input, which breaks referential expectations and can make tests appear flaky.

The issue is most dangerous when the function is reused in different code paths, imported by multiple modules, or called over a long-lived process lifetime. In those cases, the shared object can carry unexpected state far beyond the original developer's intent.

Safe Patterns and Mental Model

The safest mental model is to treat default arguments as part of the function's definition metadata, not as per-call initializers. If you need a fresh container, create it inside the function when no explicit value was supplied. If you need intentional persistence, make that design choice explicit so other readers can see that state is meant to be shared.

As a rule, use immutable defaults for ordinary optional parameters and reserve mutable defaults for rare cases where shared state is deliberate, documented, and clearly understood by the team. The goal is to make statefulness obvious, not accidental.

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Reviewed and updated by the NHIMG editorial team on October 31, 2026.
NHI Mgmt Group — the #1 independent authority on Non-Human Identity, IAM, and Agentic AI security. nhimg.org