{"record":{"id":"1638229081441455","repo":"Textualize/textual","slug":"unable-to-parse-action-args-str-r-in-action-act","errorCode":null,"errorMessage":"unable to parse {action_args_str!r} in action {action!r}","messagePattern":"unable to parse (.+?) in action (.+?)","errorType":"exception","errorClass":"ActionError","httpStatus":null,"severity":"error","filePath":"src/textual/actions.py","lineNumber":48,"sourceCode":"        action: String containing action.\n\n    Raises:\n        ActionError: If the action has invalid syntax.\n\n    Returns:\n        Action name and arguments.\n    \"\"\"\n    args_match = re_action_args.match(action)\n    if args_match is not None:\n        action_name, action_args_str = args_match.groups()\n        if action_args_str:\n            try:\n                # We wrap `action_args_str` to be able to disambiguate the cases where\n                # the list of arguments is a comma-separated list of values from the\n                # case where the argument is a single tuple.\n                action_args: tuple[Any, ...] = ast.literal_eval(f\"({action_args_str},)\")\n            except Exception:\n                raise ActionError(\n                    f\"unable to parse {action_args_str!r} in action {action!r}\"\n                )\n        else:\n            action_args = ()\n    else:\n        action_name = action\n        action_args = ()\n\n    namespace, _, action_name = action_name.rpartition(\".\")\n\n    return namespace, action_name, action_args\n","sourceCodeStart":30,"sourceCodeEnd":60,"githubUrl":"https://github.com/Textualize/textual/blob/06dbeef4bb70fb718236aa418ed658ef4667a126/src/textual/actions.py#L30-L60","documentation":"ActionError raised when action argument strings cannot be parsed. Textual parses 'app.some_action(1, \"x\")' strings by wrapping args in parentheses and running ast.literal_eval; any syntax that literal_eval rejects triggers this error.","triggerScenarios":"Posting actions with malformed argument syntax, e.g. notify('app.tick(1,') , unbalanced quotes, name expressions, or f-string interpolated values that produce invalid literals.","commonSituations":"Building action strings dynamically from user input or f-strings that inject unquoted/broken values; actions defined in keybindings with typos.","solutions":["Quote string args explicitly in the action string: f\"app.open({path!r})\"","Pass only literals (numbers, strings, tuples, booleans, None) — never variable names or calls","Validate/escape user-supplied values before embedding them in action strings"],"exampleFix":"# before\naction = f\"app.open({filename})\"  # bare name → literal_eval fails\n\n# after\naction = f\"app.open({filename!r})\"  # quoted string literal","handlingStrategy":"fallback","validationCode":"import ast\ndef safe_action_args(argstr: str) -> bool:\n    try:\n        ast.literal_eval(f\"({argstr},)\")\n        return True\n    except Exception:\n        return False","typeGuard":null,"tryCatchPattern":"try:\n    app.post_message(action)\nexcept ActionError:\n    # fall back to no-arg action or message-based dispatch\n    app.post_message(action_name_only)","preventionTips":["Always repr() string values interpolated into action strings","Only embed literals, never expressions","Validate user input before building action strings"],"tags":["actions","parsing","literal-eval","textual"],"backgroundTag":"dynamic-string-parse-failed","analyzedSha":"06dbeef4bb70fb718236aa418ed658ef4667a126","analyzedAt":"2026-08-27T02:36:57.214Z","schemaVersion":2},"datasetVersion":"2026-08-27T03:17:27.898Z"}