Textualize/textual · error · AppFail
App {name!r} not found in {lib!r}
Error message
App {name!r} not found in {lib!r} What it means
Raised by Textual's import_app() when an app is imported from a Python file (not an installed package) and the name given before the colon (e.g. "foo.py:myapp") does not exist as a global variable in that file. Textual loads the file with runpy and looks up the requested name in the module's global namespace, so a typo or an app that lives inside a function/if-main guard will not be found. The error is wrapped in AppFail, which is what CLI commands like `textual run` and the SVG screenshot tool report.
Source
Thrown at src/textual/_import_app.py:76
if drive:
lib = os.path.join(drive, os.sep, lib)
if lib.endswith(".py") or shebang_python(Path(lib)):
path = os.path.abspath(lib)
sys.path.append(str(Path(path).parent))
try:
global_vars = runpy.run_path(path, {})
except Exception as error:
raise AppFail(str(error))
sys.argv[:] = [path, *argv]
if name:
# User has given a name, use that
try:
app = global_vars[name]
except KeyError:
raise AppFail(f"App {name!r} not found in {lib!r}")
else:
# User has not given a name
if "app" in global_vars:
# App exists, lets use that
try:
app = global_vars["app"]
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
)View on GitHub (pinned to 06dbeef4bb)
Solutions
- Verify the exact global name in the target file and use it after the colon: `textual run foo.py:app` where `app = MyApp()` exists at module level in foo.py
- Add a module-level assignment `app = MyApp()` to the file
- If you only have a class, either instantiate it at module level or pass the class-name variable that exists as a global
- Omit the name entirely (just `foo.py`) so Textual auto-discovers a global `app` or a unique App subclass/instance
Example fix
# before
# foo.py
class MyApp(App): ...
if __name__ == "__main__":
MyApp().run()
# CLI: textual run foo.py:app -> AppFail
# after
# foo.py
class MyApp(App): ...
app = MyApp()
# CLI: textual run foo.py:app Defensive patterns
Strategy: validation
Validate before calling
import runpy, inspect
from textual.app import App
def find_app_global(path: str, name: str) -> object | None:
g = runpy.run_path(path)
return g.get(name) Type guard
def is_app(obj: object) -> TypeGuard[App]:
return isinstance(obj, App) or (inspect.isclass(obj) and issubclass(obj, App)) Try / catch
from textual.app import App
try:
app = import_app("foo.py:myapp")
except AppFail as e:
print(f"Bad app reference: {e}") # prompt user / fix path:name Prevention
- Always assign `app = MyApp()` at module level in entry files
- Standardize the variable name `app` across the project
- In CI, import the entry file and assert `app` exists before running textual commands
When it happens
Trigger: Calling textual's take_svg_screenshot or `textual run foo.py:myapp` where foo.py has no module-level variable named myapp; the app is instantiated inside `if __name__ == "__main__":` so no global name exists; the name is misspelled or uses different casing than the variable in the file.
Common situations: Apps created from templates that define `class MyApp(App)` but never assign `app = MyApp()` at module level; renaming the app variable in the file but not in the CLI argument; passing a class name when the file only has an instance (or vice versa); running the screenshot command from a docs/snippet file where the app is defined inside a function.
Related errors
- Unable to find app in {lib!r}, try specifying app with "foo.
- Multiple apps found {lib!r}, try specifying app with "foo.py
- 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/8194aaad8b726c6e.
Report an issue: GitHub.