Skip to content

Fix IndexError in variable bound propagators during constraint solving failures#256

Merged
mballance merged 5 commits intomasterfrom
copilot/fix-indexerror-in-rangelist
Feb 1, 2026
Merged

Fix IndexError in variable bound propagators during constraint solving failures#256
mballance merged 5 commits intomasterfrom
copilot/fix-indexerror-in-rangelist

Conversation

Copy link
Contributor

Copilot AI commented Jan 15, 2026

When using vsc.rangelist() with tuple syntax in randomize_with contexts, unsolvable constraints trigger IndexError: list index out of range instead of the expected SolveFailure.

@vsc.randobj  
class C():  
    def __init__(self):  
        self.a = vsc.rand_uint8_t()  
      
    @vsc.constraint  
    def constr(self):  
        self.a > 128  

c = C()  
with c.randomize_with() as it:  
    it.a in vsc.rangelist((0, 50))  # IndexError (BUG)
    it.a in vsc.rangelist(0, 50)    # SolveFailure (correct)

Root Cause

The bug occurred in the variable bound propagators during constraint solving. In variable_bound_min_propagator.py, after trimming self.target.domain.range_l on line 39, the local variable range_l still referenced the old list. When constraints were unsolvable and the list became empty, subsequent attempts to access range_l[0][0] raised IndexError.

Changes

  • Added _safe_to_expr_model() helper in types.py: Extracts expression models directly via .em attribute and wraps pop_expr() in try-except to handle stack corruption gracefully
  • Updated rangelist.__init__, append, __contains__: Use the helper instead of direct to_expr()/pop_expr() calls
  • Fixed variable_bound_min_propagator.py: Update local range_l reference after trimming and add safety check before accessing array elements
  • Fixed variable_bound_max_propagator.py: Add safety check and update local reference after trimming for consistency
  • Added regression tests: Verify both tuple and multi-arg syntax raise SolveFailure consistently

The fix ensures correct exception propagation throughout the constraint solving pipeline, from expression model creation through variable bound propagation.

[!WARNING]

Original prompt

This section details on the original issue you should resolve

<filter_complete></filter_complete>

<issue_title>Bug: IndexError instead of SolveFailure when using tuple syntax in rangelist with unsolvable constraints</issue_title>
<issue_description>### Description

When using vsc.rangelist() with tuple syntax to specify a range constraint that conflicts with other constraints, PyVSC throws an IndexError instead of the expected SolveFailure exception. The same constraint using multi-argument syntax correctly throws SolveFailure.

Minimal Reproducible Example

import vsc  
  
@vsc.randobj  
class C():  
    def __init__(self):  
        self.a = vsc.rand_uint8_t()  
      
    @vsc.constraint  
    def constr(self):  
        self.a &gt; 128  
  
# Case 1: Tuple syntax - throws IndexError (BUG)  
c = C()  
try:  
    with c.randomize_with() as it:  
        it.a in vsc.rangelist((0, 50))  
except Exception as e:  
    print("Exception:", type(e), e)  
    # Output: 
    # Exception: </issue_description>

<agent_instructions>Initialize the project by running `python -m venv packages/python ; ./packages/python/bin/pip install ivpm ; ./packages/python/bin/ivpm update`. Add a unit test based on the minimum reproducible in this issue. Confirm that it fails. Investigate the bug and propose a fix</agent_instructions>

## Comments on the Issue (you are @copilot in this section)

<comments>
</comments>
Original prompt

This section details on the original issue you should resolve

<issue_title>Bug: IndexError instead of SolveFailure when using tuple syntax in rangelist with unsolvable constraints</issue_title>
<issue_description>### Description

When using vsc.rangelist() with tuple syntax to specify a range constraint that conflicts with other constraints, PyVSC throws an IndexError instead of the expected SolveFailure exception. The same constraint using multi-argument syntax correctly throws SolveFailure.

Minimal Reproducible Example

import vsc  
  
@vsc.randobj  
class C():  
    def __init__(self):  
        self.a = vsc.rand_uint8_t()  
      
    @vsc.constraint  
    def constr(self):  
        self.a > 128  
  
# Case 1: Tuple syntax - throws IndexError (BUG)  
c = C()  
try:  
    with c.randomize_with() as it:  
        it.a in vsc.rangelist((0, 50))  
except Exception as e:  
    print("Exception:", type(e), e)  
    # Output: 
    # Exception: <class 'IndexError'> list index out of range  
  
# Case 2: Multi-argument syntax - correctly throws SolveFailure  
c = C()  
try:  
    with c.randomize_with() as it:  
        it.a in vsc.rangelist(0, 50)  
except Exception as e:  
    print("Exception:", type(e), e)  
    # Output: 
    # Solve failure: set 'solve_fail_debug=1' for more details
    # Exception: <class 'vsc.model.solve_failure.SolveFailure'> solve failure

Expected Behavior

Both cases should throw SolveFailure since the constraints are unsolvable:

  • Class constraint: self.a > 128
  • Inline constraint: self.a must be in range [0, 50] (tuple case) or equal to 0 or 50 (multi-arg case)

These constraints cannot be satisfied simultaneously, so both should result in SolveFailure.

Actual Behavior

  • Tuple syntax vsc.rangelist((0, 50)) throws IndexError: list index out of range
  • Multi-argument syntax vsc.rangelist(0, 50) correctly throws SolveFailure

Impact

This bug makes debugging constraint issues more difficult since:

  • The error message is misleading (IndexError instead of constraint-related error)
  • Users cannot rely on consistent exception types for the same type of constraint conflict
  • It may mask the actual constraint solving problem

</issue_description>

<agent_instructions>Initialize the project by running python -m venv packages/python ; ./packages/python/bin/pip install ivpm ; ./packages/python/bin/ivpm update. Add a unit test based on the minimum reproducible in this issue. Confirm that it fails. Investigate the bug and propose a fix</agent_instructions>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 3 commits January 15, 2026 14:49
…stack

Co-authored-by: mballance <1340805+mballance@users.noreply.github.com>
Co-authored-by: mballance <1340805+mballance@users.noreply.github.com>
Co-authored-by: mballance <1340805+mballance@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix IndexError when using tuple syntax in rangelist Fix IndexError in rangelist with tuple syntax during constraint solving failures Jan 15, 2026
Copilot AI requested a review from mballance January 15, 2026 15:04
@mballance
Copy link
Member

@copilot Have a look at the failures and address

…aint solving

Co-authored-by: mballance <1340805+mballance@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jan 15, 2026

@copilot Have a look at the failures and address

Fixed in b62b958. The root cause was in variable_bound_min_propagator.py where after trimming range_l on line 39, the code still referenced the old local variable instead of the updated list, causing IndexError on empty lists. Updated both min and max propagators to maintain proper local references after list modifications.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • github.com (HTTP Only)
    • Triggering command: /usr/bin/ssh /usr/bin/ssh -o SendEnv=GIT_PROTOCOL git@github.com git-upload-pack &#39;fvutils/pyucis.git&#39; (packet block)
    • Triggering command: /usr/bin/ssh /usr/bin/ssh -o SendEnv=GIT_PROTOCOL git@github.com git-upload-pack &#39;google/riscv-dv.git&#39; (packet block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI changed the title Fix IndexError in rangelist with tuple syntax during constraint solving failures Fix IndexError in variable bound propagators during constraint solving failures Jan 15, 2026
@mballance mballance marked this pull request as ready for review February 1, 2026 17:42
@mballance mballance merged commit c039eb6 into master Feb 1, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: IndexError instead of SolveFailure when using tuple syntax in rangelist with unsolvable constraints

2 participants