Fix TemplateNotFound: jinja2.exceptions.TemplateNotFound: index.html in Flask
This error means Jinja2 cannot locate the template file. Flask looks for templates in a 'templates' folder relative to the application or blueprint. Fix it by ensuring the template file exists in the correct templates directory, the folder is named exactly 'templates', and the path passed to render_template matches the file structure.
Reading the Stack Trace
Here's what each line means:
- File "/app/app/routes.py", line 8, in index: The route handler calls render_template('index.html') which triggers the template lookup.
- File "/app/venv/lib/python3.12/site-packages/flask/templating.py", line 150, in render_template: Flask delegates to Jinja2's template loader, which searches the configured template directories.
- jinja2.exceptions.TemplateNotFound: index.html: Jinja2 searched all registered template paths and could not find a file named index.html.
Common Causes
1. Templates folder in wrong location
The templates directory is not in the expected location relative to the Flask app or blueprint.
# Directory structure:
# app/
# __init__.py
# routes.py
# index.html <-- wrong! should be in templates/
@app.route('/')
def index():
return render_template('index.html')
2. Blueprint template folder not set
A blueprint does not specify its template_folder, so Flask does not know where to look for its templates.
auth_bp = Blueprint('auth', __name__) # no template_folder arg
@auth_bp.route('/login')
def login():
return render_template('auth/login.html') # not found
3. Typo in template name
The filename passed to render_template does not match the actual file on disk due to a typo or case mismatch.
@app.route('/')
def index():
return render_template('Index.html') # file is index.html (lowercase)
The Fix
Move the template file into the 'templates' subdirectory relative to the Flask application or blueprint. Flask's default Jinja2 loader expects templates in a folder named exactly 'templates' next to the module that defines the app.
# app/routes.py
@app.route('/')
def index():
return render_template('index.html')
# File is at app/index.html (wrong location)
# app/routes.py
@app.route('/')
def index():
return render_template('index.html')
# File moved to app/templates/index.html (correct location)
Testing the Fix
import pytest
from app import create_app
@pytest.fixture
def client():
app = create_app()
app.config['TESTING'] = True
return app.test_client()
def test_index_renders_template(client):
response = client.get('/')
assert response.status_code == 200
assert b'<!DOCTYPE html>' in response.data or b'<html' in response.data
def test_index_does_not_raise_template_not_found(client):
response = client.get('/')
assert response.status_code != 500
Run your tests:
pytest tests/ -v
Pushing Through CI/CD
git checkout -b fix/flask-template-not-found,git add app/templates/index.html,git commit -m "fix: move template to correct templates directory",git push origin fix/flask-template-not-found
Your CI config should look something like this:
name: CI
on:
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.12'
cache: 'pip'
- run: pip install -r requirements.txt
- run: pytest tests/ -v --tb=short
- run: flake8 app/
The Full Manual Process: 18 Steps
Here's every step you just went through to fix this one bug:
- Notice the error alert or see it in your monitoring tool
- Open the error dashboard and read the stack trace
- Identify the file and line number from the stack trace
- Open your IDE and navigate to the file
- Read the surrounding code to understand context
- Reproduce the error locally
- Identify the root cause
- Write the fix
- Run the test suite locally
- Fix any failing tests
- Write new tests covering the edge case
- Run the full test suite again
- Create a new git branch
- Commit and push your changes
- Open a pull request
- Wait for code review
- Merge and deploy to production
- Monitor production to confirm the error is resolved
Total time: 30-60 minutes. For one bug.
Or Let bugstack Fix It in Under 2 minutes
Every step above? bugstack does it automatically.
Step 1: Install the SDK
pip install bugstack
Step 2: Initialize
import bugstack
bugstack.init(api_key=os.environ["BUGSTACK_API_KEY"])
Step 3: There is no step 3.
bugstack handles everything from here:
- Captures the stack trace and request context
- Pulls the relevant source files from your GitHub repo
- Analyzes the error and understands the code context
- Generates a minimal, verified fix
- Runs your existing test suite
- Pushes through your CI/CD pipeline
- Deploys to production (or opens a PR for review)
Time from error to fix deployed: Under 2 minutes.
Human involvement: zero.
Try bugstack Free →No credit card. 5-minute setup. Cancel anytime.
Deploying the Fix (Manual Path)
- Verify the template file exists in the correct templates directory.
- Open a pull request with the file relocation.
- Wait for CI checks to pass on the PR.
- Have a teammate review and approve the PR.
- Merge to main and verify the page renders correctly in staging.
Frequently Asked Questions
BugStack verifies the template exists in the correct directory, renders it without errors, and runs your test suite to confirm no other templates are affected.
BugStack never pushes directly to production. Every fix goes through a pull request with full CI checks, so your team can review it before merging.
Yes. Pass template_folder='my_templates' to the Flask() or Blueprint() constructor to use a custom directory name.
Your Dockerfile may not COPY the templates directory. Ensure your COPY command includes the templates folder in the build context.