Fix ImportError: cannot import name 'app' from 'main' in Flask
This error occurs when Python cannot find the 'app' name in the 'main' module, usually due to circular imports, incorrect module paths, or the Flask app being defined with a different variable name. Fix it by restructuring imports to avoid circular dependencies or using an application factory pattern.
Reading the Stack Trace
Here's what each line means:
- from main import app: The entry point tries to import app from the main package, triggering the package's __init__.py.
- from main.routes import bp: __init__.py imports from routes.py, which in turn tries to import from main, creating a circular dependency.
- most likely due to a circular import: Python detected that main is only partially initialized because it's still executing __init__.py when routes.py tries to import from it.
Common Causes
1. Circular import between app and routes
The main module imports routes, and routes imports app from main, creating a circular dependency that prevents either from fully loading.
# main/__init__.py
from flask import Flask
app = Flask(__name__)
from main.routes import bp
app.register_blueprint(bp)
# main/routes.py
from main import app
from flask import Blueprint
bp = Blueprint('main', __name__)
@bp.route('/')
def index():
return 'Hello'
2. Wrong module name in import
The import path references 'main' but the Flask app is defined in a file or package with a different name.
# The app is in application.py, not main.py
# run.py
from main import app # Wrong: should be from application import app
The Fix
Use the application factory pattern to break the circular import. The create_app function defers route imports until after Flask is initialized, and routes use Blueprint instead of importing the app directly.
# main/__init__.py
from flask import Flask
app = Flask(__name__)
from main.routes import bp
app.register_blueprint(bp)
# main/routes.py
from main import app
from flask import Blueprint
bp = Blueprint('main', __name__)
@bp.route('/')
def index():
return 'Hello'
# main/__init__.py
from flask import Flask
def create_app():
app = Flask(__name__)
from main.routes import bp
app.register_blueprint(bp)
return app
# main/routes.py
from flask import Blueprint
bp = Blueprint('main', __name__)
@bp.route('/')
def index():
return 'Hello'
# run.py
from main import create_app
app = create_app()
if __name__ == '__main__':
app.run(debug=True)
Testing the Fix
import pytest
from main import create_app
@pytest.fixture
def app():
app = create_app()
app.config['TESTING'] = True
return app
@pytest.fixture
def client(app):
return app.test_client()
def test_index_returns_200(client):
response = client.get('/')
assert response.status_code == 200
def test_index_returns_hello(client):
response = client.get('/')
assert response.data == b'Hello'
def test_app_is_created(app):
assert app is not None
assert app.config['TESTING'] is True
Run your tests:
pytest
Pushing Through CI/CD
git checkout -b fix/circular-import-flask,git add main/__init__.py main/routes.py run.py,git commit -m "fix: use application factory pattern to resolve circular imports",git push origin fix/circular-import-flask
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.11'
- run: pip install -r requirements.txt
- run: pytest --tb=short
- run: flake8 .
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)
- Run pytest locally to confirm the factory pattern resolves the import error.
- Open a pull request with the restructured imports.
- Wait for CI checks to pass on the PR.
- Have a teammate review the application factory changes.
- Merge to main and verify the app starts correctly in staging.
Frequently Asked Questions
BugStack verifies the app starts without import errors, runs the full test suite, and confirms all routes are registered and responding correctly.
All fixes are submitted as pull requests. Your CI pipeline validates the app starts and passes tests before you review and merge.
It's a Flask pattern where you define a create_app() function that builds and configures the app. This avoids circular imports and makes testing easier by allowing multiple app instances.
You can, but you must be careful with import ordering. The factory pattern is recommended by the Flask documentation as the standard approach for non-trivial applications.