Skip to content

Python: fix {{range}} handlebars helper crashing on consecutive invalid args#14120

Open
Osamaali313 wants to merge 1 commit into
microsoft:mainfrom
Osamaali313:fix/handlebars-range-helper-skip
Open

Python: fix {{range}} handlebars helper crashing on consecutive invalid args#14120
Osamaali313 wants to merge 1 commit into
microsoft:mainfrom
Osamaali313:fix/handlebars-range-helper-skip

Conversation

@Osamaali313

Copy link
Copy Markdown

Problem

_range (in python/semantic_kernel/prompt_template/utils/handlebars_system_helpers.py, backing the {{range}} helper) drops non-integer args by mutating the list while iterating it:

args = list(args)
for index, arg in enumerate(args):
    if not isinstance(arg, int):
        try:
            args[index] = int(arg)
        except ValueError:
            args.pop(index)   # mutating during enumerate()

args.pop(index) shifts the remaining elements left, so the arg immediately after a dropped one is skipped and never validated/converted. That leftover string then reaches range(), raising TypeError.

A single invalid arg works (existing test: {{range 'a' 5}}[0, 1, 2, 3, 4]), but two consecutive invalid args crash:

{{range 'a' 'b' 5}}  ->  TypeError: 'str' object cannot be interpreted as an integer

which contradicts the helper's drop-invalid-args behavior.

Reproduction (real function)

_range(None, 'a', 5)        -> [0, 1, 2, 3, 4]
_range(None, 'a', 'b', 5)   -> TypeError   (expected [0, 1, 2, 3, 4])

Fix

Build the converted list without mutating during iteration (and tolerate int(None)TypeError alongside ValueError):

converted = []
for arg in args:
    if isinstance(arg, int):
        converted.append(arg)
    else:
        try:
            converted.append(int(arg))
        except (ValueError, TypeError):
            continue
args = converted

All existing outputs are unchanged.

Test

Adds ("range", "'a' 'b' 5", "[0, 1, 2, 3, 4]") to the parametrized helper test in python/tests/unit/prompt_template/test_handlebars_prompt_template.py — it raises TypeError on the old code and passes after the fix.

_range (backing the {{range}} helper) dropped non-integer args with args.pop(index) while iterating the same list via enumerate(args). Removing an element shifts the remaining items left, so the arg right after a dropped one is skipped and never validated; that leftover string then reaches range(), raising TypeError. A single invalid arg works (existing test: range 'a' 5 -> [0,1,2,3,4]), but two consecutive invalid args (range 'a' 'b' 5) crash, contradicting the helper's drop-invalid-args behavior.

Build the converted-args list without mutating during iteration, and also tolerate int(None) (TypeError) in addition to ValueError. All existing outputs are unchanged. Adds a regression test.
@Osamaali313 Osamaali313 requested a review from a team as a code owner June 27, 2026 15:21
Copilot AI review requested due to automatic review settings June 27, 2026 15:21

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@moonbox3 moonbox3 added the python Pull requests for the Python Semantic Kernel label Jun 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

python Pull requests for the Python Semantic Kernel

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants