Python bir hata mesajı verdiğinde en önemli bilgi son satırdadır: önce istisnanın sınıfı (NameError, TypeError gibi), iki noktadan sonra ne olduğunu anlatan mesaj gelir. Hemen üstündeki satırlar hatanın hangi dosyada, hangi satırda ve hangi ifadede oluştuğunu gösterir. Yeni Python sürümleri bu mesajlara giderek daha fazla öneri ekliyor; "Did you mean ...?" ile biten bir satır çoğu zaman çözümün kendisidir.
Bu yazıda yeni başlayanların ve deneyimli geliştiricilerin en sık karşılaştığı hata mesajlarını tek tek çalıştırıp gerçek çıktılarını gösteriyoruz: söz dizimi ve girinti hataları, NameError, UnboundLocalError, TypeError, AttributeError, KeyError, IndexError, içe aktarma hataları ve diğerleri. Tüm mesajlar Python 3.15.2 ile alındı; dosya yolunu ornek.py olarak kısalttık, başka bir şeyi değiştirmedik. Eski sürümlerde aynı hata farklı ya da daha az yardımcı bir mesajla görünebilir.
Bir traceback nasıl okunur?

Programın çalışması sırasında yakalanmayan bir istisna oluştuğunda Python bir traceback (geri izleme) yazdırır. İlk satır her zaman "Traceback (most recent call last):" olur; yani en son yapılan çağrı en altta yer alır. Her çağrı için bir File "...", line N, in ... satırı ve altında o satırın kaynak kodu görünür. 3.11 ile gelen PEP 657 sayesinde traceback, hatanın ifadenin tam olarak hangi parçasında oluştuğunu ^ ve ~ işaretleriyle vurgular. 3.13 ile traceback terminalde varsayılan olarak renkli yazılır; bu, PYTHON_COLORS, NO_COLOR ve FORCE_COLOR ortam değişkenleriyle denetlenebilir.
sayac = 0
def artir():
sayac += 1
artir()
# Traceback (most recent call last):
# File "ornek.py", line 6, in <module>
# artir()
# ~~~~~^^
# File "ornek.py", line 4, in artir
# sayac += 1
# ^^^^^
# UnboundLocalError: cannot access local variable 'sayac' where it is not associated with a valueBu traceback'i aşağıdan yukarı okuyalım: hata UnboundLocalError, 4. satırdaki artir fonksiyonunun içinde, sayac adında oluştu; o fonksiyon da 6. satırda modül düzeyinden çağrılmıştı. İç içe çağrılarda sorun genellikle kendi yazdığınız en alttaki satırdadır; standart kütüphane dosyalarına ait satırlar çoğunlukla yanlış argümanın nereden geldiğini gösterir.
Söz dizimi hataları farklı görünür: program hiç çalışmadan, ayrıştırma aşamasında yakalandıkları için "Traceback" satırı ve çağrı zinciri yoktur, yalnızca dosya, satır ve işaret gösterilir.
SyntaxError: söz dizimi hataları
SyntaxError, ayrıştırıcının kodu Python kurallarına uygun bulmadığı anlamına gelir. Yorumlayıcı hatayı fark ettiği yeri işaretler; ancak asıl eksik bazen bir önceki satırdadır. En sık görülen biçimler şunlardır. Bloğu açan satırda iki nokta eksikse:
sayi = 5
if sayi > 3
print('büyük')
# File "ornek.py", line 2
# if sayi > 3
# ^
# SyntaxError: expected ':'Anahtar kelime yanlış yazıldığında Python 3.14 ile gelen öneri devreye girer:
whille True:
break
# File "ornek.py", line 1
# whille True:
# ^^^^^^
# SyntaxError: invalid syntax. Did you mean 'while'?Kapatılmamış tırnak ve parantez hataları, sorunun başladığı yeri gösterir. Parantez örneğinde hata 1. satırda bildiriliyor, çünkü açılan köşeli parantez hiç kapanmadı:
print('merhaba)
# File "ornek.py", line 1
# print('merhaba)
# ^
# SyntaxError: unterminated string literal (detected at line 1)liste = [1, 2, 3
print(liste)
# File "ornek.py", line 1
# liste = [1, 2, 3
# ^
# SyntaxError: '[' was never closedKarşılaştırma yerine atama yazmak ve argümanlar arasındaki virgülü unutmak için de özel ipuçları var:
x = 5
if x = 5:
pass
# File "ornek.py", line 2
# if x = 5:
# ^^^^^
# SyntaxError: invalid syntax. Maybe you meant '==' or ':=' instead of '='?print('Sonuç' 42)
# File "ornek.py", line 1
# print('Sonuç' 42)
# ^^^^^^^^^^
# SyntaxError: invalid syntax. Perhaps you forgot a comma?3.14 ile else bloğundan sonra gelen elif için de ayrı bir mesaj eklendi. Koşul yapısının doğru sırası için if elif else yazısına bakabilirsiniz:
def f(x):
if x > 0:
return 'pozitif'
else:
return 'değil'
elif x == 0:
return 'sıfır'
# File "ornek.py", line 6
# elif x == 0:
# ^^^^
# SyntaxError: 'elif' block follows an 'else' blockIndentationError ve TabError
Python blokları girintiyle belirlediği için girinti hataları SyntaxError sınıfının alt sınıfı olan IndentationError ile bildirilir. İki noktayla biten bir satırdan sonra girintili blok gelmezse mesaj, bloğu açan satırı da söyler:
if True:
print('girinti yok')
# File "ornek.py", line 2
# print('girinti yok')
# ^^^^^
# IndentationError: expected an indented block after 'if' statement on line 1Tersine, beklenmeyen yerde fazladan girinti varsa:
def f():
x = 1
y = 2
# File "ornek.py", line 3
# y = 2
# IndentationError: unexpected indentAynı blokta sekme (tab) ve boşluk karıştırıldığında IndentationError sınıfının alt sınıfı olan TabError oluşur. Aşağıdaki kodun üçüncü satırı boşluk yerine bir sekme karakteriyle girintilenmiştir:
def f():
x = 1
y = 2
# TabError: inconsistent use of tabs and spaces in indentationNameError ve UnboundLocalError

NameError, tanımlanmamış bir adın kullanıldığını söyler. Yazım hatası yapılmışsa yorumlayıcı yakın bir ad önerir; standart kütüphane modülünü içe aktarmayı unuttuysanız bunu da hatırlatır:
toplam_tutar = 150
print(toplam_tuttar)
# Traceback (most recent call last):
# File "ornek.py", line 2, in <module>
# print(toplam_tuttar)
# ^^^^^^^^^^^^^
# NameError: name 'toplam_tuttar' is not defined. Did you mean: 'toplam_tutar'?print(math.pi)
# Traceback (most recent call last):
# File "ornek.py", line 1, in <module>
# print(math.pi)
# ^^^^
# NameError: name 'math' is not defined. Did you forget to import 'math'?UnboundLocalError, NameError sınıfının alt sınıfıdır ve yazının başındaki örnekte gördüğümüz gibi bir fonksiyon içinde, değer atanmadan önce okunan yerel değişken için fırlatılır. Fonksiyonun herhangi bir yerinde bir ada atama yapılırsa o ad bütün fonksiyon boyunca yerel kabul edilir; sayac += 1 hem okuma hem atama olduğu için modül düzeyindeki sayac görülmez. Çözüm, gerçekten global değişkeni değiştirmek istiyorsanız global sayac yazmak ya da daha iyisi değeri parametre olarak alıp sonuç döndürmektir. Kurallar kapsam, global ve nonlocal yazısında.
TypeError: yanlış tip ya da yanlış çağrı
TypeError, bir işlemin uygun olmayan tipte bir nesneye uygulandığını gösterir. Belki de en sık görüleni metinle sayıyı + ile birleştirmektir:
yas = 30
print('Yaş: ' + yas)
# Traceback (most recent call last):
# File "ornek.py", line 2, in <module>
# print('Yaş: ' + yas)
# ~~~~~~~~^~~~~
# TypeError: can only concatenate str (not "int") to strÇözüm str(yas) ile dönüştürmek ya da f-string kullanmaktır: f'Yaş: {yas}'. Fonksiyon çağrılarında eksik ya da yanlış adlı argümanlar da TypeError verir; yanlış yazılmış anahtar kelime argümanı için 3.13 ile öneri geldi:
def selam(ad, soyad):
return f'{ad} {soyad}'
selam('Ayşe')
# Traceback (most recent call last):
# File "ornek.py", line 4, in <module>
# selam('Ayşe')
# ~~~~~^^^^^^^^
# TypeError: selam() missing 1 required positional argument: 'soyad'print('a,b,c'.split(max_split=1))
# Traceback (most recent call last):
# File "ornek.py", line 1, in <module>
# print('a,b,c'.split(max_split=1))
# ~~~~~~~~~~~~~^^^^^^^^^^^^^
# TypeError: split() got an unexpected keyword argument 'max_split'. Did you mean 'maxsplit'?Değiştirilemez nesneyi değiştirmeye çalışmak, uzunluğu olmayan bir nesneye len() uygulamak ve hash edilemeyen bir nesneyi kümeye ya da sözlük anahtarına koymak da aynı sınıftadır. Son durum için 3.14 ile mesaj netleşti:
kume = set()
kume.add(['liste'])
# Traceback (most recent call last):
# File "ornek.py", line 2, in <module>
# kume.add(['liste'])
# ~~~~~~~~^^^^^^^^^^^
# TypeError: cannot use 'list' as a set element (unhashable type: 'list')t = (1, 2, 3)
t[0] = 9
# TypeError: 'tuple' object does not support item assignmentlen(5)
# TypeError: object of type 'int' has no len()Bu son iki örnekte traceback'in yalnızca son satırını gösterdik. Hash edilebilirlik kuralını set ve küme işlemleri, tuple konusunu tuple ve unpacking yazısında anlattık.
AttributeError: olmayan öznitelik ya da metot
AttributeError, bir nesnede bulunmayan bir öznitelik ya da metoda erişildiğinde oluşur. Python 3.15 ile bu mesaj, başka dillerden gelen alışkanlıkları tanıyacak şekilde genişledi: JavaScript'teki push ya da toUpperCase yazıldığında Python karşılığı öneriliyor.
sepet = ['elma']
sepet.push('armut')
# Traceback (most recent call last):
# File "ornek.py", line 2, in <module>
# sepet.push('armut')
# ^^^^^^^^^^
# AttributeError: 'list' object has no attribute 'push'. Did you mean '.append'?metin = 'python'
metin.toUpperCase()
# Traceback (most recent call last):
# File "ornek.py", line 2, in <module>
# metin.toUpperCase()
# ^^^^^^^^^^^^^^^^^
# AttributeError: 'str' object has no attribute 'toUpperCase'. Did you mean '.upper'?En yaygın AttributeError türlerinden biri 'NoneType' object has no attribute ... mesajıdır. Bu, bir değişkenin beklediğiniz nesne yerine None tuttuğunu söyler. Genellikle return içermeyen bir fonksiyonun sonucunu kullanmaktan ya da list.sort() gibi yerinde değiştirip None döndüren bir metodun sonucunu bir değişkene atamaktan kaynaklanır:
None.upper()
# Traceback (most recent call last):
# File "ornek.py", line 1, in <module>
# None.upper()
# ^^^^^^^^^^
# AttributeError: 'NoneType' object has no attribute 'upper'Kendi sınıflarınızda yanlış öznitelik adı kullandığınızda, yakın bir ad yoksa öneri gelmez; bu durumda sınıfın __init__ metodunda hangi adların tanımlandığına bakın. 3.15 ile bir nesnenin içindeki başka bir öznitelik üzerinden erişilebilen ad için '.inner.area' biçiminde iç yol önerisi de eklendi. Sınıf ve öznitelik kavramları için class ve nesne yazısına bakın.
KeyError ve IndexError
KeyError sözlükte olmayan bir anahtara köşeli parantezle erişildiğinde, IndexError bir dizinin sınırları dışındaki bir indekse erişildiğinde oluşur. KeyError mesajı yalnızca eksik anahtarı gösterir:
fiyatlar = {'çay': 20}
print(fiyatlar['kahve'])
# Traceback (most recent call last):
# File "ornek.py", line 2, in <module>
# print(fiyatlar['kahve'])
# ~~~~~~~~^^^^^^^^^
# KeyError: 'kahve'gunler = ['Pzt', 'Sal']
print(gunler[5])
# IndexError: list index out of rangeAnahtarın olmayabileceği durumlarda fiyatlar.get('kahve', 0) gibi varsayılan değer veren get() metodu ya da in kontrolü kullanın; seçenekler sözlük metotları yazısında. Dilimleme (gunler[2:10]) sınır dışında hata vermez, sessizce kırpılır; yalnızca tek indeksle erişim IndexError verir.
ModuleNotFoundError ve ImportError
ModuleNotFoundError, ImportError sınıfının alt sınıfıdır ve modül hiç bulunamadığında fırlatılır. Üç tipik nedeni vardır: modül adı yanlış yazılmıştır, paket kurulu değildir ya da kurulu olduğu sanal ortam etkin değildir.
import reqests
# Traceback (most recent call last):
# File "ornek.py", line 1, in <module>
# import reqests
# ModuleNotFoundError: No module named 'reqests'Modül bulunduğu ama içinden istenen ad bulunamadığında ise ImportError oluşur ve yakın bir ad varsa önerilir:
from math import sqr
# ImportError: cannot import name 'sqr' from 'math' (unknown location). Did you mean: 'sqrt'?Sık yapılan bir hata da betiğinize standart kütüphane modülüyle aynı adı vermektir. Örneğin random.py adlı bir dosyada import random yazarsanız Python kendi dosyanızı içe aktarır. 3.13 ile bu durum için açıklayıcı bir mesaj geldi (dosya yolunu kısalttık):
$ python random.py
Traceback (most recent call last):
File "C:\...\golge\random.py", line 1, in <module>
import random
File "C:\...\golge\random.py", line 2, in <module>
print(random.randint(5))
^^^^^^^^^^^^^^
AttributeError: module 'random' has no attribute 'randint' (consider renaming 'C:\...\golge\random.py' since it has the same name as the standard library module named 'random' and prevents importing that standard library module)3.15 ile ImportError ve ModuleNotFoundError nesnelerinin repr() çıktısı, oluşturulurken anahtar kelimeyle verildiyse name ve path değerlerini de gösteriyor; tembel içe aktarmadaki döngüler için yeni ImportCycleError sınıfı eklendi. İçe aktarma kuralları modül ve paket import yazısında.
ValueError, ZeroDivisionError, FileNotFoundError ve RecursionError
ValueError, tipi doğru ama değeri uygunsuz bir argümanı gösterir. Kullanıcı girdisini sayıya çevirmek bunun en tanıdık örneğidir; açma (unpacking) sırasında eleman sayısı uyuşmadığında da aynı sınıf kullanılır:
print(int('12a'))
# Traceback (most recent call last):
# File "ornek.py", line 1, in <module>
# print(int('12a'))
# ~~~^^^^^^^
# ValueError: invalid literal for int() with base 10: '12a'a, b = [1, 2, 3]
# ValueError: too many values to unpack (expected 2, got 3)print(10 / 0)
# ZeroDivisionError: division by zeroopen('olmayan.txt')
# FileNotFoundError: [Errno 2] No such file or directory: 'olmayan.txt'FileNotFoundError, OSError sınıfının alt sınıfıdır ve çoğunlukla göreli yolun programın çalıştığı klasöre göre çözülmesinden kaynaklanır; betiğin bulunduğu klasöre göre değil. Yolları güvenli kurmak için pathlib yazısına bakabilirsiniz. Sonu olmayan özyinelemede ise yorumlayıcı aynı satırın tekrarlarını tek satırda özetler:
def sonsuz(n):
return sonsuz(n + 1)
sonsuz(0)
# [Previous line repeated 996 more times]
# RecursionError: maximum recursion depth exceededRecursionError, RuntimeError sınıfından türer ve özyineleme derinliği sys.getrecursionlimit() sınırını aştığında fırlatılır. Çözüm sınırı artırmak değil, durma koşulunu (base case) eklemektir.
Hata sınıfları arasındaki akrabalık
Yerleşik istisnalar bir sınıf hiyerarşisi oluşturur ve bu hiyerarşiyi bilmek hem mesajları yorumlamayı hem de doğru except bloğunu yazmayı kolaylaştırır. Yukarıda gördüğümüz hataların çoğu birbirinin alt sınıfıdır: ModuleNotFoundError bir ImportError, UnboundLocalError bir NameError, TabError bir IndentationError, o da bir SyntaxError türüdür. UnicodeDecodeError sonunda ValueError ailesine, FileNotFoundError OSError ailesine, RecursionError RuntimeError ailesine bağlanır. Üst sınıfı yakalayan bir except bloğu alt sınıfları da yakalar:
print(issubclass(ModuleNotFoundError, ImportError))
# çıktı: True
print(issubclass(UnboundLocalError, NameError))
# çıktı: True
print(issubclass(TabError, SyntaxError))
# çıktı: True
print(issubclass(UnicodeDecodeError, ValueError))
# çıktı: True
print(issubclass(KeyError, LookupError), issubclass(IndexError, LookupError))
# çıktı: True True
print(issubclass(KeyboardInterrupt, Exception))
# çıktı: FalseSon satır önemli bir ayrıntıyı gösteriyor: Ctrl-C ile oluşan KeyboardInterrupt, Exception sınıfından değil doğrudan BaseException sınıfından türer. Belgeler bunun, except Exception yazan kodun kullanıcının programı durdurmasını yanlışlıkla engellememesi için yapıldığını açıklar. KeyError ve IndexError ise ortak LookupError üst sınıfını paylaşır; ikisini birden yakalamak istediğinizde bu sınıfı kullanabilirsiniz.
Özet tablo
| Hata | Tipik neden | İlk bakılacak yer |
|---|---|---|
| SyntaxError | Eksik iki nokta, tırnak, parantez, virgül | İşaretlenen satır ve bir önceki satır |
| IndentationError / TabError | Eksik, fazla ya da karışık girinti | Editörün sekme ayarı |
| NameError | Yazım hatası, import unutmak | Did you mean önerisi |
| UnboundLocalError | Fonksiyonda atamadan önce okuma | global, nonlocal ya da parametre |
| TypeError | Yanlış tip, eksik argüman, hash edilemeyen anahtar | Değerlerin type() sonucu |
| AttributeError | Olmayan metot, None değer | Değişkenin gerçekte ne tuttuğu |
| KeyError / IndexError | Olmayan anahtar, sınır dışı indeks | get(), in, len() |
| ModuleNotFoundError | Yanlış ad, kurulu olmayan paket, etkin olmayan venv | Hangi python çalışıyor |
| ValueError | Uygunsuz değer, açma sayısı uyuşmazlığı | Girdinin kendisi |
| FileNotFoundError | Göreli yol, yanlış klasör | Çalışma klasörü |
Hata mesajlarıyla çalışırken iyi alışkanlıklar

- Önce son satırı okuyun: istisna sınıfı ve mesaj sorunun türünü söyler; sonra yukarı doğru kendi kodunuza ait en alttaki satırı bulun.
- Önerileri ciddiye alın: "Did you mean" önerileri yazım hatalarının büyük kısmını doğrudan çözer.
- Hatayı sessizce yutmayın:
except Exception: passtraceback'i yok eder. Beklenen hataları adıyla yakalayın; yöntemler try/except rehberinde. - Sürümünüzü bilin: bu yazıdaki önerilerin bir kısmı 3.13, 3.14 ve 3.15 ile geldi; eski sürümlerde mesaj daha kısa olabilir. Yenilikler için Python 3.15 yenilikleri.
- Kendi istisnalarınıza açıklayıcı mesaj yazın: raise ve özel istisna yazısında
add_note()ile ek bilgi eklemeyi anlattık.
Sık Sorulan Sorular
SyntaxError ile diğer hatalar arasındaki fark nedir?
SyntaxError kod çalışmadan önce, ayrıştırma sırasında oluşur; dosyanın hiçbir satırı çalışmaz. Diğer istisnalar çalışma zamanında oluşur ve hata satırına kadar olan kod çalışmış olur.
Hata mesajları Türkçe gösterilebilir mi?
Python'un yerleşik hata mesajları İngilizce üretilir. Bu yazıdaki tablo ve açıklamalar mesajları Türkçe yorumlamanıza yardımcı olmak için hazırlandı.
Öneri satırı neden except içinde print(e) yazınca görünmüyor?
"Did you mean" önerileri, istisna yakalanmadan traceback olarak görüntülendiğinde eklenir; istisna nesnesinin str() değerinin parçası değildir. Bu yüzden print(e) yalnızca temel mesajı yazar.
Traceback'te renkleri nasıl kapatırım?
NO_COLOR ortam değişkenini ayarlayın ya da yalnızca Python için PYTHON_COLORS=0 kullanın. Belgelere göre PYTHON_COLORS, NO_COLOR üzerinde; NO_COLOR da FORCE_COLOR üzerinde önceliklidir.
Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.
İlgili içerikler: Python öğrenme rehberi · try/except hata yönetimi · raise ve özel istisna · Kapsam ve UnboundLocalError · Modül ve import · Python 3.15 yenilikleri