How It Works Features Pricing Blog Error Guides
Log In Start Free Trial
Flask · Python

Fix RuntimeError: RuntimeError: Working outside of application context in Flask

This error occurs when you access Flask objects like current_app, g, or db outside of a request or application context. Flask requires an active application context for these operations. Fix it by wrapping the code in with app.app_context(): or ensuring it runs inside a request handler, CLI command, or test fixture that provides the context.

Reading the Stack Trace

Traceback (most recent call last): File "/app/scripts/seed_db.py", line 5, in <module> from app.models import User File "/app/app/models.py", line 8, in <module> class User(db.Model): File "/app/venv/lib/python3.12/site-packages/flask_sqlalchemy/extension.py", line 265, in __getattr__ return getattr(self._get_current_object(), name) File "/app/venv/lib/python3.12/site-packages/werkzeug/local.py", line 316, in _get_current_object raise RuntimeError(unbound_message) from None RuntimeError: Working outside of application context. This typically means that you attempted to use functionality that needed the current application. To solve this, set up an application context with app.app_context().

Here's what each line means:

Common Causes

1. Standalone script without app context

A script imports app models or uses current_app without pushing an application context first.

# scripts/seed_db.py
from app.models import User
from app import db

user = User(name='Admin')
db.session.add(user)
db.session.commit()  # RuntimeError: outside app context

2. Background task accessing Flask globals

A background thread or Celery task tries to access current_app or g without an application context.

import threading
from flask import current_app

def background_job():
    print(current_app.config['API_KEY'])  # no context

thread = threading.Thread(target=background_job)
thread.start()

3. Test missing app context fixture

A test accesses Flask objects but the test fixture does not provide an application context.

def test_user_model():
    user = User(name='Test')  # RuntimeError if no app_context
    assert user.name == 'Test'

The Fix

Create an application instance and use with app.app_context(): to push an application context before accessing Flask-SQLAlchemy or other Flask extensions. This gives Flask the configuration and state it needs to process your operations.

Before (broken)
# scripts/seed_db.py
from app.models import User
from app import db

user = User(name='Admin')
db.session.add(user)
db.session.commit()
After (fixed)
# scripts/seed_db.py
from app import create_app, db
from app.models import User

app = create_app()
with app.app_context():
    user = User(name='Admin')
    db.session.add(user)
    db.session.commit()
    print(f'Created user: {user.name}')

Testing the Fix

import pytest
from app import create_app, db
from app.models import User

@pytest.fixture
def app():
    app = create_app()
    app.config['TESTING'] = True
    app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///:memory:'
    with app.app_context():
        db.create_all()
        yield app
        db.drop_all()

def test_user_creation_within_context(app):
    with app.app_context():
        user = User(name='Test')
        db.session.add(user)
        db.session.commit()
        assert user.id is not None

def test_current_app_accessible_in_context(app):
    with app.app_context():
        from flask import current_app
        assert current_app.config['TESTING'] is True

Run your tests:

pytest tests/ -v

Pushing Through CI/CD

git checkout -b fix/flask-app-context-script,git add scripts/seed_db.py,git commit -m "fix: wrap script in app_context for Flask context access",git push origin fix/flask-app-context-script

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:

  1. Notice the error alert or see it in your monitoring tool
  2. Open the error dashboard and read the stack trace
  3. Identify the file and line number from the stack trace
  4. Open your IDE and navigate to the file
  5. Read the surrounding code to understand context
  6. Reproduce the error locally
  7. Identify the root cause
  8. Write the fix
  9. Run the test suite locally
  10. Fix any failing tests
  11. Write new tests covering the edge case
  12. Run the full test suite again
  13. Create a new git branch
  14. Commit and push your changes
  15. Open a pull request
  16. Wait for code review
  17. Merge and deploy to production
  18. 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:

  1. Captures the stack trace and request context
  2. Pulls the relevant source files from your GitHub repo
  3. Analyzes the error and understands the code context
  4. Generates a minimal, verified fix
  5. Runs your existing test suite
  6. Pushes through your CI/CD pipeline
  7. 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)

  1. Run pytest locally to confirm all contexts are properly managed.
  2. Open a pull request with the context fix.
  3. Wait for CI checks to pass on the PR.
  4. Have a teammate review and approve the PR.
  5. Merge to main and verify scripts and background tasks work in staging.

Frequently Asked Questions

BugStack verifies the script runs successfully within an app context, confirms no context leaks, and runs your full test suite before marking it safe to deploy.

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.

App context provides access to current_app and g. Request context adds request and session. A request context automatically pushes an app context, but not vice versa.

Yes. Use the pattern @celery.task(bind=True) and push an app context inside the task, or configure Celery with Flask's app factory to auto-push contexts.