mutated × unstructured — blows up live on input you didn't expect
Stale API After Upgrade (AttributeError)
A mixin reaches for a method a dependency upgrade quietly renamed or removed.
01the recipe
In the wild
compound ofMacro & Mixin MisuseVersion & Library MismanagementCWE-1104compoundCWE-758 Undefined BehaviorCWE-754 Unchecked Condition
example.py
# SMELL: a mixin assumes a method a dependency upgrade renamed/removed.
# (macro / mixin misuse x version / library mismanagement)
class Audited(Base):
def save(self):
self.log_change() # provided by Base... until v3 renamed it
super().save() # AttributeError the first time this path runs
# RIGHT: pin the contract and adapt at the seam, not deep in a mixin.
class Audited(Base):
def save(self):
getattr(self, "log_change", self._audit_fallback)()
super().save()A mixin reaches for an inherited method a library upgrade quietly dropped; nothing fails at import, only when that path executes after deploy. It relies on behavior the new version no longer guarantees.
// observed
bug: AttributeError: 'Audited' object has no attribute 'log_change' right: missing hook degrades to a fallback, not a crash
02weakness catalog
Mapped weaknesses (CWE)
On its own, this defect is catalogued by MITRE as one or more of these weaknesses. The exploitable vulnerability usually appears only when it chains or combines with another.