Krikri::TaskExecutor::WhenEvaluationError
Evaluates task.when_condition (if any) against vars_context, printing "skipping: [...]" and bumping the skipped counter when it's false - shared by execute_task_once and the batch-group trigger path (execute_batch_group) so both interpret when: identically.
defer_stats: when true (a loop item), the skipped counter is NOT
bumped here. Real Ansible counts a looped task once in the recap, not
once per skipped item - loop-aggregation happens once in
finish_looped_task, so a loop that ends up with zero executed items is
recorded as a single "skipped". Deferring avoids per-item skipped
inflation (a 5-item all-skipped loop must be skipped=1, not skipped=5).
Raised by when_passes? when evaluating a when: condition itself
raises (e.g. mounts | selectattr(...) | first on an empty match -
FilterEngine's own first/last raise "No first item, sequence
was empty." rather than silently returning nil, matching real
Jinja2's do_first). This used to crash the ENTIRE process with an
unhandled-exception stack trace - when_passes? has 7 call sites
across solo/looped/batched task execution and meta:, none of
which caught it. Real Ansible degrades to one clean failed task
("Task failed: Error while evaluating conditional: ...") and
continues the run, not a crash.
when_passes? itself raises rather than swallowing so each call
site can decide how to represent the failure in ITS OWN result
shape - a solo/looped task (execute_task_once,
execute_looped_task_batched) can turn this into a real failed: true result that flows through the exact same
finish_single_task/finish_looped_task aggregation a normal
task failure does (so a looped when: failure correctly shows
failed=1, not skipped=1, in the recap - matching real
Ansible's own "One or more items failed"); a bare meta:/
include_vars:/batch-group-member check that has no such result
pipeline falls back to swallow_when_error, which replicates
exactly what this method used to do inline (stats/halt/register/
print, respecting ignore_errors:) and returns false - reusing
the same "don't run this task" signal every caller already treats
a when:-skip as.