Bug description

Traceback (most recent call last): File "/app/.venv/lib/python3.11/site-packages/flask_appbuilder/base.py", line 52, in dynamic_class_import return reduce(getattr, tmp[1:], package) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AttributeError: module 'superset_config' has no attribute 'MyDashboardView' 2025-07-31 09:48:09,920:ERROR:flask_appbuilder.base:An error occurred when importing declared addon superset_config.MyDashboardView: module 'superset_config' has no attribute 'MyDashboardView' 2025-07-31 09:48:09,920:INFO:superset.initialization:Setting database isolation level to READ COMMITTED 2025-07-31 09:48:09,920:ERROR:flask_appbuilder.base:module 'superset_config' has no attribute 'MyDashboardView' Traceback (most recent call last): File "/app/.venv/lib/python3.11/site-packages/flask_appbuilder/base.py", line 52, in dynamic_class_import return reduce(getattr, tmp[1:], package) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2025-07-31 09:48:09,921:ERROR:superset.app:Failed to create app Traceback (most recent call last): File "/app/superset/app.py", line 40, in create_app app_initializer.init_app() File "/app/superset/initialization/init.py", line 479, in init_app self.init_app_in_ctx() File "/app/superset/initialization/init.py", line 401, in init_app_in_ctx self.configure_fab() File "/app/superset/utils/decorators.py", line 266, in wrapped return on_error(ex) ^^^^^^^^^^^^ File "/app/superset/utils/decorators.py", line 236, in on_error raise ex File "/app/superset/utils/decorators.py", line 259, in wrapped result = func(args, *kwargs) ^^^^^^^^^^^^^^^^^^^^^ File "/app/superset/initialization/init.py", line 561, in configure_fab appbuilder.init_app(self.superset_app, db.session) File "/app/.venv/lib/python3.11/site-packages/flask_appbuilder/base.py", line 211, in init_app self.sm = self.security_manager_class(self)

ITS VERIFIED THAT THIS CLASS IS PRESENT IN THE CONFIG file via deriving it from the IndexView class and the class authlib should be imported in FAB right...

I have also made sure the class is passed correctly to FAC_INDEX_VIEW via

FAB_INDEX_VIEW = f"{MyDashboardView.module}.{MyDashboardView.name}"

Screenshots/recordings

No response

Superset version

master / latest-dev

Python version

3.11

Node version

18 or newer

Browser

Chrome

Additional context

No response

Checklist

  • [x] I have searched Superset docs and Slack and didn't find a solution to my problem.
  • [x] I have searched the GitHub issue tracker and didn't find a similar bug report.
  • [x] I have checked Superset's logs for errors and if I found a relevant Python stacktrace, I included it here as text in the "additional context" section.

Comment From: dosubot[bot]

This error usually means that Superset can't find MyDashboardView as a top-level attribute in your superset_config.py at the time it tries to import it dynamically. Here’s what to check:

  1. Make sure MyDashboardView is defined at the top level of superset_config.py (not inside a function, class, or conditional). It should look like:
from flask_appbuilder import expose, IndexView
from superset.typing import FlaskResponse

class MyDashboardView(IndexView):
    @expose("/")
    def index(self) -> FlaskResponse:
        # your custom logic here
        pass

FAB_INDEX_VIEW = f"{MyDashboardView.__module__}.{MyDashboardView.__name__}"

Reference: example

  1. If you’re running Superset in Docker, the config file must be named superset_config_docker.py and placed in ./docker/pythonpath_dev/ on your host (which maps to /app/pythonpath in the container). Otherwise, set the SUPERSET_CONFIG_PATH environment variable to the full path of your config file inside the container and restart Superset. If the config file isn’t loaded, your class won’t be visible to the import logic details.

  2. Check for syntax or import errors in superset_config.py. Any error will prevent the module from loading, and Superset will log the failure.

  3. Confirm that FAB_INDEX_VIEW is set to the correct string: 'superset_config.MyDashboardView' if the class is in superset_config.py.

If you’ve checked all of the above and still see the error, please share the relevant portion of your superset_config.py so we can look for subtle issues.

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Chat with Dosu Join Discord Share on X

Comment From: paulsonkevgit

I have looked into those issues already,

Small code snippet(WELCOME_PAGE_REDIRECT_DEFAULT='/welcome/form')

class MyDashboardView(IndexView): @expose("/") def index(self) -> FlaskResponse: if not g.user or not get_user_id(): # Do steps for anonymous user e.g. return redirect("/login") # Do steps for authenticated user e.g. return redirect(WELCOME_PAGE_REDIRECT_DEFAULT)

def view9(SupersetsetApp): from superset.views.user_D.views import DashboardModelView3 import time appbuilder.add_view_no_menu(DashboardModelView3) appbuilder.add_link( "Welcome Form", label=("Information"), href="/welcome/form", icon="fa-dashboard", category="", category_icon="", )

FLASK_APP_MUTATOR=view9

FAB_INDEX_VIEW = f"{MyDashboardView.module}.{MyDashboardView.name}"

IT USED TO WORK UNTIL version 4 but the issue arised after migrating to Superset version 5

Comment From: dosubot[bot]

The error is likely because your config file fails to load fully, so MyDashboardView never becomes available as a module attribute. In your snippet, FLASK_APP_MUTATOR is set to view9, but there’s no definition for view9—this will cause an import error and prevent the config from loading, which in turn makes MyDashboardView unavailable for dynamic import. Try either removing or correcting this assignment (e.g., set FLASK_APP_MUTATOR = view1 if that’s what you meant).

Also, make sure your config file is in the correct location and named properly for your environment: if you’re running in Docker Compose, it should be superset_config_docker.py in ./docker/pythonpath_dev/ on your host. Otherwise, set the SUPERSET_CONFIG_PATH environment variable to the config’s full path inside the container. If the config isn’t loaded, Superset won’t see your custom class, no matter how it’s defined (details).

Finally, check the Superset logs for any syntax or import errors in your config file—any error will prevent all attributes (including MyDashboardView) from being available for dynamic import (reference). Fixing these should resolve the AttributeError.

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Chat with Dosu Join Discord Share on X

Comment From: paulsonkevgit

I have looked into those issues already, the view1 was a typo , it was view9 itself in def In docker i used : SUPERSET_CONFIG_PATH=/app/superset/superset_config.py And at that location i have put my superset_config.py file....

Comment From: dosubot[bot]

Superset 5 no longer supports customizing the main IndexView using FAB_INDEX_VIEW in the config file. Instead, you need to use FLASK_APP_MUTATOR to programmatically set appbuilder.indexview before views are registered. This is a breaking change from v4 and is why your previous approach now fails (source).

Here's how you can migrate your custom IndexView logic:

from flask_appbuilder import expose, IndexView
from superset.typing import FlaskResponse

class MyDashboardView(IndexView):
    @expose("/")
    def index(self) -> FlaskResponse:
        # your custom logic here
        pass

def mutate_app(app):
    from superset.extensions import appbuilder
    appbuilder.indexview = MyDashboardView
    # register other views/links as needed

FLASK_APP_MUTATOR = mutate_app

Remove FAB_INDEX_VIEW from your config. Make sure your FLASK_APP_MUTATOR function sets appbuilder.indexview to your custom class before registering any views. If you still have issues, check your logs for config loading errors and confirm that other config changes are taking effect (source).

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Chat with Dosu Join Discord Share on X

Comment From: paulsonkevgit

But why would it then say that the attribute is not found even if its defined in the superset_config.py

Comment From: dosubot[bot]

Superset reports that the attribute isn't found—even if it's defined in your superset_config.py—when the config file fails to load completely and without errors. Any syntax, import, or runtime error anywhere in superset_config.py (even unrelated to MyDashboardView) will prevent the module from being fully imported, so none of its attributes (including MyDashboardView) are available for dynamic import, resulting in the AttributeError you see. This is how Python module loading works, and Superset logs these failures during startup—check your logs for any import errors or exceptions during config loading for clues about what went wrong "source".

On top of that, Superset 5 no longer supports customizing the main IndexView using FAB_INDEX_VIEW in the config file. That pattern is now ignored, so even if your class is present, Superset won't use it. You must use FLASK_APP_MUTATOR to programmatically set appbuilder.indexview before views are registered "source".

So: check your logs for config import errors, make sure superset_config.py loads without any errors, and migrate your IndexView customization to FLASK_APP_MUTATOR. If the config loads cleanly and you use the new pattern, your custom class will be picked up.

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Chat with Dosu Join Discord Share on X

Comment From: paulsonkevgit

CHECKED and verified this (check your logs for config import errors, make sure superset_config.py loads without any errors) THe superset_config.py is not loading...

in my code i have already used:: FLASK_APP_MUTATOR=view9

Comment From: dosubot[bot]

In Docker Compose, Superset expects custom config overrides at ./docker/pythonpath_dev/superset_config_docker.py on your host (which maps to /app/pythonpath/superset_config_docker.py in the container). Placing your config at /app/superset/superset_config.py and setting SUPERSET_CONFIG_PATH can cause import issues or prevent the config from loading, especially if there are path or PYTHONPATH mismatches. The recommended approach is to move your config to ./docker/pythonpath_dev/superset_config_docker.py, remove SUPERSET_CONFIG_PATH, and restart your containers. Check your logs for "Loaded your Docker configuration at [...]" to confirm it's picked up—if you see "Using default Docker config...", your override isn't being loaded. If you want to test that Superset is attempting to load your config, add raise Exception("test") at the top of superset_config_docker.py and look for the error in the logs. This should help you pinpoint why your config isn't loading and get your customizations working again.
Reference Docker config docs

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Chat with Dosu Join Discord Share on X