
Khi viết code Python, việc gặp phải lỗi liên quan đến khoảng trắng là điều hết sức bình thường, đặc biệt với những ai mới chuyển từ các ngôn ngữ dùng dấu ngoặc nhọn {} sang. Lỗi này chặn đứng việc thực thi chương trình ngay lập tức, nhưng tin vui là cách khắc phục lại vô cùng đơn giản. Bài viết này sẽ hướng dẫn bạn cách đọc thông báo lỗi để sửa tay nhanh chóng, cũng như cách thiết lập môi trường để không bao giờ gặp lại lỗi này nữa.
Bạn xem thêm:
- SyntaxError Missing Colon: 2 Cách Sửa Lỗi Thiếu Dấu ‘:’ Python
- Sửa Lỗi IndentationError Unindent Python: 2 Cách Triệt Để
- Hướng dẫn đếm số ký tự trong chuỗi Python (Kèm code chuẩn)
💡 Trả lời nhanh: Lỗi IndentationError: unexpected indent xảy ra khi bạn có một dòng code bị dư khoảng trắng (dấu cách) ở đầu dòng so với cấu trúc khối lệnh hiện tại. Để sửa nhanh, hãy xem dòng báo lỗi trong Terminal (Traceback), tìm đến đúng dòng đó trong file code và xóa các dấu cách thừa ở đầu dòng cho đến khi nó thẳng hàng với các câu lệnh cùng cấp phía trên.
Đề bài
Bạn đang chạy một script Python và chương trình đột ngột dừng lại, văng ra một thông báo lỗi màu đỏ chót trên Terminal/Console có dòng chữ IndentationError: unexpected indent.
Input: Một đoạn mã nguồn Python (thường là copy từ nơi khác hoặc do lỡ tay gõ phím) chứa các dòng lệnh không tuân thủ đúng quy tắc căn lề.
Output: Yêu cầu bạn phải tìm ra dòng code bị lỗi, chuẩn hóa lại khoảng trắng theo đúng chuẩn PEP 8 (sử dụng 4 spaces cho mỗi cấp độ thụt lề), giúp chương trình chạy thành công.
Ràng buộc: Trình biên dịch của Python 3.12 cực kỳ nghiêm ngặt về whitespace. Nó tuyệt đối không cho phép bạn trộn lẫn giữa Tab và Space trong cùng một khối lệnh, đồng thời yêu cầu sự thẳng hàng tuyệt đối.
Phân tích nguyên nhân sinh ra lỗi thụt lề thừa python
Lỗi IndentationError: unexpected indent trong Python xảy ra khi một dòng code bị thụt lề (indent) sâu hơn mức cần thiết một cách vô lý, mà không thuộc về bất kỳ cấu trúc điều khiển nào trước đó (như if, for, while, hoặc def).
Không giống như C++, Java hay JavaScript dùng cặp dấu ngoặc nhọn {} để gom nhóm các câu lệnh lại với nhau, Python sử dụng chính các khoảng trắng (whitespace) ở đầu mỗi dòng để định nghĩa phạm vi của một khối lệnh (block of code). . Khi trình thông dịch (interpreter) của Python đọc code của bạn từ trên xuống dưới, nó luôn ghi nhớ “mức độ thụt lề hiện tại”.
Nếu nó bất ngờ gặp một dòng có số lượng khoảng trắng nhiều hơn mức hiện tại, mà dòng ngay trước đó lại không phải là một câu lệnh mở khối (không kết thúc bằng dấu hai chấm :), nó sẽ bối rối và ném ra lỗi unexpected indent (thụt lề không mong đợi).
📌 Góc nhìn thực tế: Trong quá trình chấm bài và hỗ trợ sinh viên năm 2 làm dự án, tôi nhận thấy đến 90% các bạn gặp lỗi này là do thói quen copy code từ StackOverflow, ChatGPT dán thẳng vào file mà không kiểm tra lại định dạng, hoặc do các bạn sử dụng chung một file code nhưng người dùng VSCode (cấu hình Space), người dùng Notepad++ (cấu hình Tab).
Giả định
Trong bài viết này, chúng ta giả định bạn đang làm việc trên một file text thông thường hoặc một IDE phổ biến. Chúng ta sẽ lấy ví dụ một đoạn code đơn giản khai báo biến và in ra màn hình, trong đó dòng in ra màn hình vô tình bị gõ dư một dấu cách.
Để giải quyết tình trạng này triệt để, chúng ta sẽ đi qua hai hướng: một là kỹ năng sinh tồn cơ bản (đọc lỗi và sửa tay), hai là kỹ năng của một kỹ sư phần mềm (cấu hình công cụ để tự động hóa).
Cách 1: Sửa thủ công để fix indentation error python
Sửa thủ công là phương pháp đọc trực tiếp thông báo lỗi (Traceback) trên terminal để tìm chính xác dòng code bị thừa khoảng trắng và xóa chúng đi. Phương pháp này yêu cầu bạn phải hiểu cách Python báo lỗi.
Ý tưởng
Bất cứ khi nào chương trình crash, Python luôn in ra một đoạn văn bản gọi là Traceback. Thay vì hoảng hốt nhìn dòng cuối cùng, chúng ta sẽ nhìn ngược lên trên một chút để thấy file nào gây lỗi và dòng số mấy chứa đoạn code sai. Từ đó, mở file ra, đưa con trỏ chuột đến đúng dòng đó và căn chỉnh lại bằng phím Backspace cho đến khi nó thẳng hàng với logic hiện tại.
Các bước tiến hành
-
Chạy chương trình Python và để lỗi xuất hiện.
-
Đọc Traceback từ dưới lên trên. Tìm dòng có chữ
File "tên_file.py", line X. (X là số thứ tự dòng). -
Mở file mã nguồn, di chuyển (scroll) đến đúng dòng số X.
-
Đặt con trỏ chuột ở ký tự đầu tiên của dòng code (sau các khoảng trắng).
-
Nhấn phím
Backspace(hoặc phím mũi tên trái + Delete) để xóa các dấu cách hoặc dấu tab thừa. -
Đảm bảo ký tự đầu tiên của dòng thẳng hàng theo chiều dọc với dòng code cùng cấp độ ngay phía trên nó.
-
Lưu file (Ctrl + S) và chạy lại chương trình.
Minh họa tay Traceback
Giả sử chúng ta có file app.py với input thử bị lỗi như sau:
def check_status():
status = "Active"
print(status) # Dòng này bị dư 1 space
Khi chạy, terminal báo:
File "/path/to/app.py", line 3
print(status)
^
IndentationError: unexpected indent
-
Phân tích Traceback: Trình biên dịch chỉ rõ lỗi nằm ở file
app.py, dòng số3. Mũi tên^chỉ ngay vào chữpcủa lệnhprint. -
Hành động: Dòng 2 (
status = "Active") thụt vào 4 spaces. Dòng 3 (print...) thụt vào 5 spaces. Bạn đưa trỏ chuột trước chữp, xóa đi 1 khoảng trắng. Cả hai dòng cùng thẳng hàng ở mốc 4 spaces. Xong!
Đánh giá phương pháp
-
Phù hợp người mới vì: Rèn luyện được kỹ năng vô cùng quan trọng: không sợ hãi khi nhìn thấy màu đỏ trong Terminal và biết cách đọc Traceback báo lỗi.
-
Ưu điểm: Nhanh gọn, thao tác tức thời, không cần cài đặt plugin hay công cụ rườm rà. Phù hợp khi bạn thi code trên các nền tảng online (HackerRank, LeetCode) với editor hạn chế.
-
Nhược điểm: Làm thủ công rất mất thời gian nếu bạn copy một đoạn code dài hàng trăm dòng bị sai lề. Ngoài ra, mắt người rất khó phân biệt giữa 1 Tab và 4 Spaces nếu chúng nhìn có vẻ thẳng hàng, dẫn đến dễ sửa đi sửa lại mà vẫn lỗi.
-
Độ phức tạp:
O(1) thời gianthao tác để sửa một dòng, nhưng sẽ làO(N)nếu phải sửa N dòng lỗi. Không tốn thêm bộ nhớ.
Cách 2: Xử lý triệt để python indentation space tab bằng IDE
Khác với Cách 1, việc cấu hình IDE (Integrated Development Environment) giúp tự động hóa quá trình chuẩn hóa thụt lề, loại bỏ hoàn toàn các ký tự khoảng trắng tàng hình gây lỗi và biến những dòng code lộn xộn vào nếp chỉ với một phím bấm.
Ý tưởng
Khác với Cách 1 ở chỗ chúng ta không dùng “mắt thường” để đếm khoảng trắng nữa. Chúng ta sẽ yêu cầu trình soạn thảo code (như VSCode hoặc PyCharm) hiển thị mọi ký tự ẩn (Render Whitespace). Sau đó, thiết lập mặc định khi nhấn phím Tab, IDE sẽ tự động sinh ra đúng 4 ký tự Space. Cuối cùng, sử dụng bộ định dạng mã (Code Formatter) như Black hoặc autopep8 để tự động căn lề toàn bộ file code.
Các bước tiến hành (trên VSCode)
-
Bật hiển thị khoảng trắng: Mở VSCode, vào Settings (Ctrl + ,) -> Tìm kiếm từ khóa
render whitespace-> Chọn all thay vì selection. Lúc này, mọi dấu cách (space) sẽ hiện thành các dấu chấm mờ·, và tab sẽ hiện thành dấu mũi tên→. Nhờ vậy bạn phát hiện ngay lỗi. -
Ép Tab thành Space: Cùng trong Settings, tìm
insert spaces. Đảm bảo tùy chọn Editor: Insert Spaces đã được tick chọn. -
Chỉnh kích thước Tab: Tìm
tab sizevà đặt Editor: Tab Size là4. -
Cài đặt Formatter: Mở mục Extensions (Ctrl+Shift+X), tìm và cài đặt extension có tên là Black Formatter (chuẩn format nghiêm ngặt nhất của Python hiện nay).
-
Tự động format: Quay lại file code của bạn, nhấn tổ hợp phím
Shift + Alt + F(trên Windows) hoặcShift + Option + F(trên Mac). Toàn bộ code sẽ tự nhảy về đúng vị trí.
Minh họa tay với Formatter
Cùng một input lỗi như Cách 1:
def check_status():
status = "Active"
print(status)
Bạn bôi đen toàn bộ đoạn code, nhấn Shift + Alt + F. Trình Formatter Black sẽ phân tích cú pháp (Abstract Syntax Tree), phát hiện ra print(status) nằm trong hàm check_status nhưng bị dư lề. Nó tự động viết lại file thành:
def check_status():
status = "Active"
print(status)
Không cần bạn phải đếm hay nhấn phím Backspace.
Khi nào nên dùng Cách 2?
Phương pháp này là bắt buộc đối với sinh viên CNTT bắt đầu làm quen với làm việc nhóm (teamwork), sử dụng Git để quản lý mã nguồn, hoặc tham gia vào bất kỳ dự án thực tế nào có quy mô từ hai file script trở lên. Cấu hình môi trường là bước đầu tiên của sự chuyên nghiệp.
Đánh giá
-
Ưu điểm: Triệt để, trị tận gốc vấn đề môi trường. Tiết kiệm hàng chục giờ đồng hồ debug những lỗi “tàng hình” liên quan đến khoảng trắng trong suốt sự nghiệp lập trình. Giúp code đồng nhất dù có bao nhiêu người tham gia dự án.
-
Nhược điểm: Cần tốn khoảng 5 phút ban đầu để vọc vạch cấu hình IDE. Đôi khi Formatter có thể làm thay đổi cấu trúc của các câu lệnh quá dài (dù đúng chuẩn nhưng có thể không hợp mắt bạn).
-
Độ phức tạp:
O(1) thời gianđể thiết lập một lần dùng mãi mãi.
So sánh nhanh 2 cách
Bảng này giúp bạn quyết định nên dùng cách nào mà không cần đọc lại toàn bài.
| Tiêu chí | Cách 1: Sửa thủ công | Cách 2: Cấu hình IDE & Formatter |
| Ý tưởng cốt lõi | Đọc báo lỗi Traceback và tự tay xóa ký tự thừa ở dòng tương ứng. | Cấu hình editor hiển thị ký tự ẩn và dùng tổ hợp phím để tự động căn lề. |
| Độ phức tạp | O(1) thao tác/dòng | O(1) thiết lập/lần |
| Dễ đọc / dễ hiểu | ★★★★★ | ★★★☆☆ |
| Hiệu năng (tiết kiệm tgian) | ★★★☆☆ | ★★★★★ |
| Phù hợp khi | Mới học căn bản, làm bài tập nhỏ, code trên web, thi online. | Làm dự án thực tế, làm việc nhóm, copy code từ bên ngoài vào dự án. |
| Không phù hợp khi | Quá nhiều file bị lỗi, hoặc file dài hàng ngàn dòng code. | Không có quyền cài đặt phần mềm (máy tính trường học khóa quyền admin). |
Code Python đầy đủ

Cách 1 — Sửa thủ công (Mô phỏng lỗi và fix):
# Tên biến nhất quán với phần minh họa tay
def solve_manual_fix(status_input):
"""
Hàm này nhận vào một trạng thái và in nó ra màn hình.
Mô phỏng code ĐÃ ĐƯỢC SỬA TAY, loại bỏ khoảng trắng thừa.
"""
# Trạng thái ban đầu (đã thụt lề chuẩn 4 spaces)
current_status = status_input
# Dòng lệnh dưới đây ĐÃ TỪNG bị lỗi: print(current_status) (dư 1 space)
# Sau khi sửa tay, nó thẳng hàng với dòng khai báo biến phía trên.
print(f"Trạng thái hiện tại: {current_status}")
return True
# --- TEST NHANH (xóa hoặc comment lại trước khi đăng) ---
# assert solve_manual_fix("Active") == True
# print("Tất cả test pass!")
# --- Nhập liệu ---
# Lưu ý: giả định input hợp lệ
user_status = "Đang hoạt động"
solve_manual_fix(user_status)
Cách 2 — Cấu hình IDE (Mô phỏng kết quả sau khi dùng Auto-Format):
# Điểm khác với Cách 1: Cấu trúc phức tạp hơn (có vòng lặp),
# mô phỏng kết quả file sau khi nhấn Shift + Alt + F bằng Formatter.
def solve_formatter_fix(item_list):
"""Lặp qua danh sách và in từng phần tử với độ thụt lề chuẩn xác"""
# Mọi dòng dưới đây đều được IDE tự động duy trì bước nhảy 4 spaces.
count = 0
for item in item_list:
# Nếu dòng này thụt 5 spaces, Black formatter sẽ tự kéo về 4 spaces
count += 1
print(f"Mục {count}: {item}")
return count
# --- TEST NHANH ---
# assert solve_formatter_fix(["A", "B"]) == 2
my_items = ["Lập trình Python", "Sửa lỗi SEO", "Tối ưu hóa"]
tong_so = solve_formatter_fix(my_items)
print(f"Đã xử lý {tong_so} mục.")
Ví dụ chạy thử
| STT | Input | Output | Giải thích |
| 1 | user_status = "Đang hoạt động" (Code Cách 1) |
Trạng thái hiện tại: Đang hoạt động |
Code đã được canh lề đúng, interpreter dịch mượt mà không vấp. |
| 2 | my_items = ["A", "B"] (Code Cách 2) |
|
Vòng lặp for nhận diện đúng block code bên trong nó nhờ khoảng trắng chuẩn. |
| 3 | File code chứa: print("Hello") ở dòng đầu tiên. |
IndentationError: unexpected indent |
Edge case: Dòng code đầu tiên của file (root level) không được phép thụt lề bất kỳ khoảng trắng nào. |
Lỗi thường gặp
Lỗi 1: Dư khoảng trắng ở lệnh ngay đầu file
Lỗi thụt lề ở cấp độ root là lỗi rất ngớ ngẩn nhưng hay gặp khi bạn vô tình tỳ tay vào bàn phím trước khi bắt đầu code.
Hiện tượng: Vừa chạy file thì terminal báo ngay IndentationError: unexpected indent tại dòng số 1, dù dòng đó chỉ là lệnh print đơn giản.
Nguyên nhân: Vì trong Python, các câu lệnh ở ngoài cùng của một module (file) bắt buộc phải nằm sát lề trái (mức độ thụt lề = 0). Việc có khoảng trắng ở đây vi phạm quy tắc cơ bản nhất của scope.
Code sai:
# output sai là: IndentationError tại dòng 1
print("Chào mừng đến với Python")
Code đúng:
# output đúng là: Chào mừng đến với Python
print("Chào mừng đến với Python")
Lỗi 2: Trộn lẫn Tab và Space (TabError)
Lỗi này là “sát thủ tàng hình” vì nhìn trên màn hình, code có vẻ rất thẳng hàng nhưng máy tính lại không hiểu.
Hiện tượng: Output văng ra dòng chữ TabError: inconsistent use of tabs and spaces in indentation.
Nguyên nhân: Vì Python 3 không cho phép bạn dùng phím Tab và phím Space xen kẽ nhau để định nghĩa các khối lệnh cùng cấp. Một lập trình viên trước đó dùng Tab, sau đó bạn vào sửa và dùng 4 Spaces, dẫn đến đụng độ môi trường.
Code sai:
# output sai là: TabError
def tinh_tong(a, b):
# Dòng này dùng Tab
ket_qua = a + b
# Dòng này dùng 4 Spaces
return ket_qua
Code đúng:
# output đúng là: Chạy bình thường, không lỗi
def tinh_tong(a, b):
# Cả hai dòng đều dùng 4 Spaces chuẩn PEP 8
ket_qua = a + b
return ket_qua
Lỗi 3: Khoảng trắng ẩn từ code copy trên mạng
Copy code từ website, blog cá nhân hoặc tài liệu PDF thường mang theo những hiểm họa mà mắt thường không thấy.
Hiện tượng: Code trông cực kỳ hoàn hảo, căn lề chuẩn chỉ nhưng vẫn dính unexpected indent hoặc lỗi ký tự lạ (Non-breaking space – \xa0).
Nguyên nhân: Vì các trang web thường dùng mã HTML (non-breaking space) để giữ định dạng văn bản hiển thị. Khi bạn bôi đen và copy, Python không coi ký tự này là khoảng trắng hợp lệ (như phím Space), dẫn đến lỗi thụt lề.
Code sai:
# output sai là: IndentationError hoặc SyntaxError
if True:
print("Lỗi do ký tự ")
Code đúng:
# output đúng là: Lỗi do ký tự
# Bạn phải bôi đen khoảng trắng đó, xóa đi và tự gõ phím Space lại.
if True:
print("Lỗi do ký tự ")
Lỗi 4: Thụt lề sai do thiếu dấu hai chấm trước đó
Đôi khi báo lỗi thụt lề nhưng nguyên nhân sâu xa lại đến từ một lỗi cú pháp ở dòng trên.
Hiện tượng: Trình soạn thảo (Editor) tự động căn lề sai, đẩy lệnh của bạn ra ngoài. Khi bạn ép nó thụt vào, nó báo lỗi unexpected indent.
Nguyên nhân: Vì bạn đã quên dấu hai chấm : ở cuối lệnh if, for, def. Trình biên dịch không nhận diện được đó là lệnh mở đầu block, nên nó coi việc bạn thụt lề ở dòng tiếp theo là vô lý.
Code sai:
# output sai là: SyntaxError hoặc IndentationError
if diem >= 5
print("Đậu") # Thụt lề này bị coi là thừa vì dòng trên thiếu dấu :
Code đúng:
# output đúng là: Đậu
if diem >= 5:
print("Đậu")
Lỗi 5: Dư khoảng trắng ở dòng trống (Empty Lines)
Lỗi này làm nhiều người bứt rứt vì trình báo lỗi chỉ vào một dòng dường như không có chữ nào.
Hiện tượng: Traceback báo lỗi ở một dòng trống xen giữa các khối lệnh.
Nguyên nhân: Vì dù dòng đó không có code, nhưng bạn lỡ để lại một vài ký tự khoảng trắng không khớp với cấp độ thụt lề của block hiện tại. Một số trình biên dịch cũ hoặc parser nghiêm ngặt sẽ bắt lỗi này, dù Python mới có thể châm chước. Tốt nhất là xóa sạch khoảng trắng ở các dòng trống.
Code sai:
# output sai là: Có thể bị báo IndentationError ở dòng trống
def chay_vong_lap():
for i in range(5):
print(i)
# Dòng này trống nhưng chứa 2 dấu cách
print("Xong")
Code đúng:
# output đúng là: In từ 0 đến 4 rồi in Xong
def chay_vong_lap():
for i in range(5):
print(i)
# Dòng này thực sự trống, không có ký tự nào
print("Xong")
Câu hỏi thường gặp
IndentationError unexpected indent là gì?
Lỗi IndentationError: unexpected indent là thông báo của Python cho biết trình biên dịch tìm thấy một dòng mã nguồn có khoảng trắng hoặc khoảng tab ở đầu dòng nhiều hơn mức quy định, không tuân theo bất kỳ cấu trúc rẽ nhánh hay vòng lặp nào phía trên nó.
Khoảng trắng (whitespace) trong Python hoạt động như thế nào và gây ra lỗi thụt lề thừa python ra sao?
Khác với các ngôn ngữ khác dùng ngoặc nhọn để chia khối lệnh, Python sử dụng khoảng trắng ở đầu dòng để xác định phạm vi của hàm, vòng lặp hay điều kiện if. Nếu bạn tùy tiện thêm khoảng trắng vào một dòng code không thuộc cấu trúc nào, Python sẽ không hiểu dòng đó thuộc về đâu và báo lỗi.
Làm thế nào để fix lỗi indentation error python trên VSCode nhanh nhất?
Cách nhanh nhất trên VSCode là bạn cài đặt extension tên là “Black Formatter”. Sau đó, bạn chỉ cần bôi đen toàn bộ mã nguồn và nhấn tổ hợp phím Shift + Alt + F (trên Windows) hoặc Shift + Option + F (trên Mac), công cụ sẽ tự động dọn dẹp mọi khoảng trắng thừa.
Nên dùng Space hay Tab để tránh lỗi python indentation space tab?
Theo tiêu chuẩn PEP 8 chính thức của Python, bạn bắt buộc phải sử dụng Space (dấu cách) để thụt lề, và cụ thể là 4 Spaces cho mỗi cấp độ khối lệnh. Việc sử dụng phím Tab bị khuyến cáo không nên dùng để tránh lỗi không đồng nhất hiển thị giữa các hệ điều hành và editor khác nhau.
Sự khác biệt giữa unexpected indent và expected an indented block là gì?
Hai lỗi này đối lập nhau. Unexpected indent xảy ra khi bạn thụt lề một dòng code trong khi không cần thiết (dư khoảng trắng). Ngược lại, expected an indented block xảy ra ngay sau các lệnh như if, for, def… khi Python đang mong chờ bạn thụt lề dòng tiếp theo nhưng bạn lại viết sát lề (thiếu khoảng trắng).
Tại sao code python bị lỗi thụt lề dù nhìn trên màn hình rất thẳng hàng?
Bởi vì mắt người không thể phân biệt được sự khác nhau giữa 1 ký tự Tab và 4 ký tự Space khi chúng hiển thị độ dài tương đương nhau trên màn hình. Python 3 cấm ngặt việc trộn lẫn hai loại ký tự này trong cùng một block. Bạn cần bật tính năng “Render Whitespace” trên IDE để nhìn rõ các ký tự ẩn này.
Làm sao kiểm tra nhanh code có bị lỗi fix indentation error python hay không trước khi chạy?
Thay vì đợi chương trình chạy rồi crash, bạn hãy cài đặt các công cụ Linter như flake8 hoặc pylint vào dự án của mình. Các công cụ này sẽ gạch dưới dòng code bị lỗi màu đỏ ngay lập tức trong lúc bạn đang gõ, giúp bạn phát hiện lỗi thụt lề thừa trước cả khi lưu file.
Kết luận
Việc sửa lỗi thụt lề thừa trong Python không đòi hỏi tư duy thuật toán phức tạp, mà cần sự tỉ mỉ và cấu hình môi trường làm việc chuẩn mực. Nếu bạn đang thi trên giấy hoặc môi trường web hạn chế, Cách 1 (đọc Traceback và sửa tay) là kỹ năng sinh tồn thiết yếu.
Tuy nhiên, nếu bạn xác định đi theo con đường lập trình phần mềm chuyên nghiệp, hãy áp dụng Cách 2: thiết lập VSCode/IDE chuẩn PEP 8 và để máy móc tự lo phần khoảng trắng cho bạn. Chúc bạn code mượt mà và không còn ám ảnh bởi những báo lỗi màu đỏ!
Các khóa học liên quan:
Một số sản phẩm từ Python:
Một số sách lập trình Python bạn hãy tham khảo