The Fix
pip install stripe==14.4.0a2
Based on closed stripe/stripe-python issue #596 · PR/commit linked
Production note: Most teams hit this during upgrades or environment changes. Roll out with a canary and smoke critical endpoints (health, OpenAPI/docs) before 100%.
@@ -134,7 +134,7 @@ def __delitem__(self, k):
# Allows for unpickling in Python 3.x
- if hasattr(self, "_unsaved_values"):
+ if hasattr(self, "_unsaved_values") and k in self._unsaved_values:
self._unsaved_values.remove(k)
Option A — Upgrade to fixed release\npip install stripe==14.4.0a2\nWhen NOT to use: Do not use del on metadata if you expect the key may not exist.\n\n
Why This Fix Works in Production
- Trigger: In [1]: from utils.stripe import stripe # (= import stripe + stripe.api_key = settings.STRIPE['SECRET_KEY'])
- Mechanism: Fixes the issue where using `del` on StripeObject.metadata raised a KeyError.
- Why the fix works: Fixes the issue where using `del` on StripeObject.metadata raised a KeyError. (first fixed release: 14.4.0a2).
- If left unfixed, the same config can fail only in production (env differences), causing startup failures or partial feature outages.
Why This Breaks in Prod
- Shows up under Python 3.5.3 in real deployments (not just unit tests).
- Surfaces as: In [1]: from utils.stripe import stripe # (= import stripe + stripe.api_key = settings.STRIPE['SECRET_KEY'])
Proof / Evidence
- GitHub issue: #596
- Fix PR: https://github.com/stripe/stripe-python/pull/599
- First fixed release: 14.4.0a2
- Reproduced locally: No (not executed)
- Last verified: 2026-02-08
- Confidence: 0.85
- Did this fix it?: Yes (upstream fix exists)
- Own content ratio: 0.36
Discussion
High-signal excerpts from the issue thread (symptoms, repros, edge-cases).
“I just released version 2.33.1, using del should no longer throw a KeyError. Though note that to unset metadata keys you'd still need to use…”
“Hi @apinsard, thanks for the report. You can unset metadata keys like this: or like this: Nevertheless, the KeyError when using the del keyword is…”
“Thank you for the quick answer and the provided workaround!”
Failure Signature (Search String)
- In [1]: from utils.stripe import stripe # (= import stripe + stripe.api_key = settings.STRIPE['SECRET_KEY'])
Error Message
Stack trace
Error Message
-------------
In [1]: from utils.stripe import stripe # (= import stripe + stripe.api_key = settings.STRIPE['SECRET_KEY'])
In [2]: pi = stripe.PaymentIntent.retrieve('pi_deadbeef')
In [3]: pi.metadata
Out[3]:
<StripeObject at 0x7f92140c5098> JSON: {
"booking_id": "13506",
"damage_deposit_amount": "20000",
"waiting_for_webhook": "True"
}
In [4]: 'foobar' in pi.metadata
Out[4]: False
In [5]: del pi.metadata['damage_deposit_amount']
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-5-e399e0ff7d29> in <module>
----> 1 del pi.metadata['damage_deposit_amount']
/usr/share/virtualenvs/cocoonr/lib/python3.5/site-packages/stripe/stripe_object.py in __delitem__(self, k)
136 # Allows for unpickling in Python 3.x
137 if hasattr(self, "_unsaved_values"):
--> 138 self._unsaved_values.remove(k)
139
140 # Custom unpickling method that uses `update` to update the dictionary
KeyError: 'damage_deposit_amount'
In [6]: pi.metadata
Out[6]:
<StripeObject at 0x7f92140c5098> JSON: {
"booking_id": "13506",
"waiting_for_webhook": "True"
}
In [7]: pi.save()
Out[7]:
<PaymentIntent payment_intent id=pi_deadbeef at 0x7f9214136598> JSON: {
...
"metadata": {
"booking_id": "13506",
"waiting_for_webhook": "True"
},
...
}
In [8
... (truncated) ...
Environment
- Python: 3.5.3
What Broke
Using del on metadata raised KeyError, causing unexpected behavior in production.
Fix Options (Details)
Option A — Upgrade to fixed release Safe default (recommended)
pip install stripe==14.4.0a2
Use when you can deploy the upstream fix. It is usually lower-risk than long-lived workarounds.
Fix reference: https://github.com/stripe/stripe-python/pull/599
First fixed release: 14.4.0a2
Last verified: 2026-02-08. Validate in your environment.
When NOT to Use This Fix
- Do not use del on metadata if you expect the key may not exist.
Did This Fix Work in Your Case?
Quick signal helps us prioritize which fixes to verify and improve.
Prevention
- Capture the exact failing error string in logs and tests so you can reproduce via a minimal script.
- Pin production dependencies and upgrade only with a reproducible test that hits the failing path.
Version Compatibility Table
| Version | Status |
|---|---|
| 14.4.0a2 | Fixed |
Related Issues
No related fixes found.
Sources
We don’t republish the full GitHub discussion text. Use the links above for context.