Python: KeyError Explained
Python raises a KeyError with a key name attached — you asked a dictionary for a key it doesn't have. Here's why it happens (often with JSON or config) and the clean ways to handle a missing key.
Python stops and names the exact key it couldn't find:
KeyError: 'email'
A KeyError means you asked a dictionary for a key it doesn't contain. Using square brackets — data['email'] — tells Python "this key definitely exists," so when it doesn't, Python raises rather than silently returning nothing. The key in the message is your biggest clue.
Why it usually happens
The value came from outside your control and didn't have the shape you assumed:
- JSON from an API where the field is optional or was renamed.
- A config file missing an entry you expected.
- A typo or case mismatch —
data['Email']vsdata['email'].
Step 1: See what keys actually exist
Before guessing, print the real keys — the answer is often a typo or a missing field:
print(data.keys()) # dict_keys(['name', 'e_mail']) ← ah, different name
Step 2: Ask safely with .get()
If a key might legitimately be absent, .get() returns None (or a default you choose) instead of raising:
email = data.get('email') # None if missing — no crash
email = data.get('email', 'n/a') # or supply a fallback
Step 3: Check membership when you need to branch
When missing vs present should do different things, test with in:
if 'email' in data:
send_to(data['email'])
else:
print('no email on file')
Square brackets mean "I promise this key exists." Use them only when you're sure; reach for
.get()whenever the data comes from somewhere you don't fully control.
The checklist
- KeyError = that exact key isn't in the dict; the message names it.
print(data.keys())— usually a typo, case, or renamed field.- Optional key? Use
data.get('key')ordata.get('key', default). - Branching on presence?
if 'key' in data:.
Stop reading, start building
This pairs with a hands-on BytExplorer course — do it on your own machine and actually keep the skill.