@@ -279,7 +279,7 @@ def _parse_failed_msg(
279279 if value_not_in_choices_error :
280280 # ignore templated value not in allowed choices
281281 choice_key = value_not_in_choices_error .group ("name" )
282- choice_value = task ["action" ][ choice_key ]
282+ choice_value = task ["action" ]. get ( choice_key )
283283 if has_jinja (choice_value ):
284284 _logger .debug (
285285 "Value checking ignored for '%s' option in task '%s' at line %s." ,
@@ -355,3 +355,28 @@ def test_args_module_pass(
355355 ]
356356 log_string = "\n " .join (record .getMessage () for record in records )
357357 assert len (records ) == 0 , log_string
358+
359+ def test_args_parse_failed_msg_no_key () -> None :
360+ """Test that _parse_failed_msg does not crash if key is missing in task."""
361+
362+ class MockTask :
363+ def __init__ (self ) -> None :
364+ self .action = {"policy" : "allow" }
365+ self .line = 1
366+
367+ def __getitem__ (self , key : str ) -> Any :
368+ return getattr (self , key )
369+
370+ rule = ArgsRule ()
371+ task = MockTask ()
372+ failed_msg = '{"msg": "value of default must be one of: allow, deny, reject"}'
373+
374+ # pylint: disable=protected-access
375+ results = rule ._parse_failed_msg ( # noqa: SLF001
376+ failed_msg ,
377+ task , # type: ignore[arg-type]
378+ "ufw" ,
379+ )
380+
381+ assert len (results ) == 1
382+ assert "value of default must be one of" in results [0 ].message
0 commit comments