class

Krikri::ConditionalEvaluator::UndefinedVariableError

Inherits Exception < Reference < Object

Raised only when raise_undefined is true (currently: task-level when: via Executor#when_passes?, which already wraps this whole call in a rescue that converts it into a real failed-task result - see WhenEvaluationError there) and evaluating the condition reaches a BARE or DOTTED variable reference (the same REGEX_BARE_VAR_REF- shaped grammar VariableSubstitutor's own strict: module-arg check already covers, see its UndefinedVariableError) that resolves to nothing. Deliberately as narrowly scoped as that existing check: only a direct lookup reaching evaluate_value's own "not found" exit raises - a filter/function chain (foo | default(...), lookup(...), any is <test>) still falls back to the lenient "undefined" sentinel regardless, since this hand-rolled evaluator's own syntax-coverage gaps already produce that same sentinel for reasons unrelated to the variable genuinely being undefined - conflating the two would turn an evaluator limitation into a spurious task failure (see UndefinedVariableError's own comment in variable_substitutor.cr for the identical reasoning applied there first).

Found live via round172's buluma.git_tag (Rocky 9.6): when: git_remote != '' and git_remote != None with git_remote genuinely undefined (no default, never set). Real Ansible raises ("'git_remote' is undefined") and fails the task (failed=1); this evaluator's lenient nil != ''/nil != None comparisons both resolved truthy instead, evaluating the whole when: as satisfied - the exact "changes final task-pass/fail state" trigger KNOWN_MISSING.md called for revisiting this with. raise_undefined is a separate flag from strict above (which checks the FINAL result's own type, for changed_when:/failed_when: - unrelated to whether an intermediate operand was undefined) - the two are independent because changed_when:/failed_when: deliberately still get the lenient undefined-operand handling here (not touched by this fix).