{"record":{"id":"97fb03a4ece6b66b","repo":"pallets/flask","slug":"failed-to-parse-app-name-r-as-an-attribute-name","errorCode":null,"errorMessage":"Failed to parse {app_name!r} as an attribute name or function call.","messagePattern":"Failed to parse (.+?) as an attribute name or function call\\.","errorType":"exception","errorClass":"NoAppException","httpStatus":null,"severity":"error","filePath":"src/flask/cli.py","lineNumber":131,"sourceCode":"        return True\n    finally:\n        # Delete tb to break a circular reference.\n        # https://docs.python.org/2/library/sys.html#sys.exc_info\n        del tb\n\n\ndef find_app_by_string(module: ModuleType, app_name: str) -> Flask:\n    \"\"\"Check if the given string is a variable name or a function. Call\n    a function to get the app instance, or return the variable directly.\n    \"\"\"\n    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:","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/pallets/flask/blob/3596b1ab61cea85edb8970e83ff61daa073facf8/src/flask/cli.py#L113-L149","documentation":"Raised by find_app_by_string when FLASK_APP's app-name portion cannot be parsed as a Python expression at all (ast.parse raises SyntaxError). This is the parsing fallback before attribute/call dispatch.","triggerScenarios":"export FLASK_APP='module:app 123' or any value whose post-colon part is not a valid Python identifier or call expression (unbalanced parens, stray operators).","commonSituations":"Typos in FLASK_APP; shell quoting that mangles the value; stray whitespace/punctuation from copy-paste.","solutions":["Use a valid Python identifier or call expression after the colon: FLASK_APP='module:app'.","Quote the whole value in the shell to avoid splitting.","Double-check balanced parentheses for call expressions."],"exampleFix":"// before\n# export FLASK_APP='module:app('  # raises\n// after\n# export FLASK_APP='module:app()'","handlingStrategy":"validation","validationCode":"import ast\ntry:\n    ast.parse(app_name.strip(), mode='eval')\nexcept SyntaxError:\n    raise ValueError('FLASK_APP value is not a valid expression')","typeGuard":"import ast\ndef is_valid_app_expr(s) -> bool:\n    try:\n        ast.parse(s.strip(), mode='eval')\n        return True\n    except SyntaxError:\n        return False","tryCatchPattern":"try:\n    app = find_app_by_string(module, app_name)\nexcept NoAppException:\n    # fix FLASK_APP and retry\n    raise","preventionTips":["Use a valid identifier or call expression after the colon.","Quote the FLASK_APP value in the shell.","Avoid stray whitespace/punctuation."],"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"}