pallets/flask · error · NoAppException

Failed to parse arguments as literal values: {app_name!r}.

Error message

Failed to parse arguments as literal values: {app_name!r}.

What it means

A `NoAppException` from `find_app_by_string` when the factory-call form was parsed but one of its arguments failed `ast.literal_eval`. Flask only accepts Python literals (strings, numbers, tuples, lists, dicts, booleans, None) as factory arguments — it will not evaluate variables, function calls, or expressions like `os.environ['X']`, since the app string is data, not executed code. literal_eval's ValueError is caught and replaced with this clearer message.

Source

Thrown at src/flask/cli.py:159

        if not isinstance(expr.func, ast.Name):
            raise NoAppException(
                f"Function reference must be a simple name: {app_name!r}."
            )

        name = expr.func.id

        # Parse the positional and keyword arguments as literals.
        try:
            args = [ast.literal_eval(arg) for arg in expr.args]
            kwargs = {
                kw.arg: ast.literal_eval(kw.value)
                for kw in expr.keywords
                if kw.arg is not None
            }
        except ValueError:
            # literal_eval gives cryptic error messages, show a generic
            # message with the full expression instead.
            raise NoAppException(
                f"Failed to parse arguments as literal values: {app_name!r}."
            ) from None
    else:
        raise NoAppException(
            f"Failed to parse {app_name!r} as an attribute name or function call."
        )

    try:
        attr = getattr(module, name)
    except AttributeError as e:
        raise NoAppException(
            f"Failed to find attribute {name!r} in {module.__name__!r}."
        ) from e

    # If the attribute is a function, call it with any args and kwargs
    # to get the real application.
    if inspect.isfunction(attr):
        try:

View on GitHub ↗ (pinned to 6a2f545bfd)

Solutions

  1. Quote string arguments and protect them from the shell: `flask --app 'myapp:create_app("production")' run` (on Windows cmd: `flask --app "myapp:create_app('production')" run`).
  2. Move dynamic logic into the factory itself (read env vars inside create_app) and call it with literals or no arguments.
  3. Restrict arguments to literal types; pass a config name string and resolve it to an object inside the factory.

Example fix

# before
flask --app 'myapp:create_app(os.environ["CONFIG"])' run

# after
flask --app 'myapp:create_app("production")' run
# or resolve inside the factory:
def create_app(config_name=None):
    config_name = config_name or os.environ.get("CONFIG", "development")
Defensive patterns

Strategy: validation

Validate before calling

import ast
for arg in ['"prod"', '8080', 'True']:
    ast.literal_eval(arg)  # raises if not a literal

Type guard

def args_are_literals(arg_strings):
    import ast
    try:
        for a in arg_strings:
            ast.literal_eval(a)
        return True
    except (ValueError, SyntaxError):
        return False

Prevention

When it happens

Trigger: `flask --app 'module:create_app(config)' run` where `config` is a bare name (not a quoted string), or arguments like `create_app(os.getenv("ENV"))`, `create_app(1+1)`, or any non-literal expression in the argument list.

Common situations: Forgetting quotes around a string argument — compounded by shells stripping the inner quotes so Flask receives `create_app(dev)` instead of `create_app("dev")`; trying to compute config dynamically inside the app string instead of inside the factory; passing objects that can't be expressed as literals.

Related errors


AI-assisted analysis of pallets/flask@6a2f545bfd (2026-07-31). Data as JSON: /data/errors/6bb6ca401b913dcb.json. Report an issue: GitHub ↗.