Textualize/textual · error · AppFail
Multiple apps found {lib!r}, try specifying app with "foo.py
Error message
Multiple apps found {lib!r}, try specifying app with "foo.py:app" What it means
When no explicit app name is given, Textual's import_app() collects every global in the file that is an App instance or App subclass; if more than one is found it cannot choose between them, so it refuses to guess and asks you to disambiguate with the `file:app` syntax. Note the message text says 'Multiple apps found' followed by the path. This commonly fires when a file defines several demo apps or imports App subclasses for use as screens.
Source
Thrown at src/textual/_import_app.py:101
except KeyError:
raise AppFail(f"App {name!r} not found in {lib!r}")
else:
# Find an App class or instance that is *not* the base class
apps = [
value
for value in global_vars.values()
if (
isinstance(value, App)
or (inspect.isclass(value) and issubclass(value, App))
and value is not App
)
]
if not apps:
raise AppFail(
f'Unable to find app in {lib!r}, try specifying app with "foo.py:app"'
)
if len(apps) > 1:
raise AppFail(
f'Multiple apps found {lib!r}, try specifying app with "foo.py:app"'
)
app = apps[0]
app._BASE_PATH = path
else:
# Assuming the user wants to import the file
sys.path.append("")
try:
module = importlib.import_module(lib)
except ImportError as error:
raise AppFail(str(error))
find_app = name or "app"
try:
app = getattr(module, find_app or "app")
except AttributeError:
raise AppFail(f"Unable to find {find_app!r} in {module!r}")View on GitHub (pinned to 06dbeef4bb)
Solutions
- Name the app explicitly: `textual run foo.py:MyApp`
- Delete or rename unused App classes so only one remains at module level
- Import other app classes inside functions rather than at module top level
Example fix
# before # foo.py class LeftApp(App): ... class RightApp(App): ... # CLI: textual run foo.py -> AppFail: Multiple apps found # after # CLI: textual run foo.py:LeftApp
Defensive patterns
Strategy: validation
Validate before calling
apps = discover_apps("foo.py") # see errorIndex 12 helper
if len(apps) > 1:
raise SystemExit("Multiple apps; specify foo.py:AppName") Try / catch
try:
app = import_app("foo.py")
except AppFail:
app = import_app("foo.py:MyApp") # disambiguate explicitly Prevention
- Keep one App class per demo file
- Import foreign app classes lazily inside functions
- Always pass the explicit name in automation scripts
When it happens
Trigger: Running `textual run foo.py` on a file that defines two or more App subclasses/instances at module level; a file that imports other app classes (e.g. `from other import OtherApp`) alongside its own app; a gallery/demo file containing many small apps.
Common situations: Demo or example files with multiple sample apps; refactoring that leaves an old app class alongside the new one; importing an app class for isinstance checks or reuse, which inadvertently registers it as a candidate global.
Related errors
- App {name!r} not found in {lib!r}
- Unable to find app in {lib!r}, try specifying app with "foo.
- Unable to find {find_app!r} in {module!r}
- SyntaxAwareDocument unavailable - tree-sitter is not install
- Can't animate attribute {attribute!r} on {obj!r}; attribute
AI-assisted analysis of Textualize/textual@06dbeef4bb (2026-08-27).
Data as JSON: /api/errors/2ab0c46128f12e17.
Report an issue: GitHub.