{"record":{"id":"fe76c88aea23f13c","repo":"pallets/flask","slug":"function-reference-must-be-a-simple-name-app-nam","errorCode":null,"errorMessage":"Function reference must be a simple name: {app_name!r}.","messagePattern":"Function reference must be a simple name: (.+?)\\.","errorType":"exception","errorClass":"NoAppException","httpStatus":null,"severity":"error","filePath":"src/flask/cli.py","lineNumber":142,"sourceCode":"    from . import Flask\n\n    # Parse app_name as a single expression to determine if it's a valid\n    # attribute name or function call.\n    try:\n        expr = ast.parse(app_name.strip(), mode=\"eval\").body\n    except SyntaxError:\n        raise NoAppException(\n            f\"Failed to parse {app_name!r} as an attribute name or function call.\"\n        ) from None\n\n    if isinstance(expr, ast.Name):\n        name = expr.id\n        args = []\n        kwargs = {}\n    elif isinstance(expr, ast.Call):\n        # Ensure the function name is an attribute name only.\n        if not isinstance(expr.func, ast.Name):\n            raise NoAppException(\n                f\"Function reference must be a simple name: {app_name!r}.\"\n            )\n\n        name = expr.func.id\n\n        # Parse the positional and keyword arguments as literals.\n        try:\n            args = [ast.literal_eval(arg) for arg in expr.args]\n            kwargs = {\n                kw.arg: ast.literal_eval(kw.value)\n                for kw in expr.keywords\n                if kw.arg is not None\n            }\n        except ValueError:\n            # literal_eval gives cryptic error messages, show a generic\n            # message with the full expression instead.\n            raise NoAppException(\n                f\"Failed to parse arguments as literal values: {app_name!r}.\"","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/pallets/flask/blob/3596b1ab61cea85edb8970e83ff61daa073facf8/src/flask/cli.py#L124-L160","documentation":"Raised by find_app_by_string when FLASK_APP parses as a call expression (ast.Call) but the function being called is not a bare name — e.g. it is an attribute access like pkg.mod.create_app or a subscript. The CLI only supports calling a simple top-level name in the module.","triggerScenarios":"export FLASK_APP='module:pkg.create_app()' or FLASK_APP='module:obj[\"factory\"]()' — function reference is an attribute/subscript, not a Name.","commonSituations":"Trying to invoke a factory nested under a submodule via dotted notation in FLASK_APP; refactoring that moved the factory into a sub-package.","solutions":["Reference a top-level name in the module: export FLASK_APP='module:create_app()'.","Add a module-level wrapper that calls the nested factory.","Import the factory into the target module's top level and reference it there."],"exampleFix":"// before\n# export FLASK_APP='app:myapp.factory()'  # raises\n// after\n# in app.py: from myapp import factory as create_app\n# export FLASK_APP='app:create_app()'","handlingStrategy":"validation","validationCode":"import ast\nexpr = ast.parse(app_name.strip(), mode='eval').body\nif isinstance(expr, ast.Call) and not isinstance(expr.func, ast.Name):\n    raise ValueError('FLASK_APP function reference must be a simple name')","typeGuard":"import ast\ndef is_simple_call(s) -> bool:\n    expr = ast.parse(s.strip(), mode='eval').body\n    return not (isinstance(expr, ast.Call) and not isinstance(expr.func, ast.Name))","tryCatchPattern":"try:\n    app = find_app_by_string(module, app_name)\nexcept NoAppException:\n    # add a top-level wrapper and retry\n    raise","preventionTips":["Reference a top-level name in the target module.","Add a wrapper for nested factories.","Keep factories importable at module scope."],"tags":["cli","flask-app-env","parsing"],"backgroundTag":null,"analyzedSha":"3596b1ab61cea85edb8970e83ff61daa073facf8","analyzedAt":"2026-08-11T20:11:52.622Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}