NVIDIA / NVIDIA/cuopt

[BUG] Incorrect capacity dimension key, unsafe new_order_data handling, and type assumptions in construct_rerouting_model

Open
#867 8 comments 0 reactions 1 assignee View on GitHub

@ramakrishnap-nv is already working on this.

Since Feb 17, 2026.

awaiting response bug
Dominant language
Cuda
Stars
1k
Forks
233
Avg merge
4d 4h
Merged PRs (30d)
95

Description

While reviewing python/cuopt/routing.py, several logical and structural issues were identified in the construct_rerouting_model function. These issues range from critical logic errors (incorrect dictionary keys) to runtime safety hazards (unsafe None handling) and API misuse.

These issues affect the correctness and robustness of the re-routing pipeline.


1. [Critical] Wrong dictionary key used for base capacity dimension

Description:
The code incorrectly uses a loop variable (name) that leaks from a previous loop scope to store the base capacity dimension. This results in the capacity data being stored under an arbitrary key (the last element of vehicle_order_matching_constraints) instead of the correct demand_name.

Vulnerable Code:

# Previous loop where 'name' is defined
for name in vehicle_order_matching_constraints:
    if name in capacity_dimensions:
        del capacity_dimensions[name]

# ... later in the code ...

# 'name' here holds the last value from the loop above!
capacity_dimensions_h[name] = { 
    "demand": order_demand,
    "capacity": vehicle_cap,
}

Expected Behavior:
The base demand dimension should be stored using the correct key variable demand_name derived earlier in the function.

Suggested Fix:

capacity_dimensions_h[demand_name] = {  # Use demand_name instead of name
    "demand": order_demand,
    "capacity": vehicle_cap,
}


2. Unsafe new_order_data handling

Description:
The function treats new_order_data as optional at the beginning but later accesses it unconditionally. If new_order_data is None, the function will crash with a TypeError.

Vulnerable Code:

# Check is optional
if new_order_data is not None:
    # validation logic...

# ... later ...
# Unconditional access -> Crash if new_order_data is None
new_order_locations_h.extend(new_order_data["order_locations"])

Suggested Fix:
Either make new_order_data mandatory check at the start:

if new_order_data is None:
    raise ValueError("new_order_data must be provided for rerouting")


3. Unsafe type assumption on get_order_service_times

Description:
The code assumes original_model.get_order_service_times() always returns a cudf.Series (or similar object with .to_arrow()). However, the API can return a dict for vehicle-specific service times. If a dict is returned, the code raises an AttributeError.

Vulnerable Code:

service_time = original_model.get_order_service_times()
# If service_time is a dict, this fails:
service_time_h = service_time.to_arrow().to_pylist()

Suggested Fix:
Add an isinstance check or handle the dictionary return type explicitly.


4. API Mismatch: Integer used instead of Boolean

Description:
The set_drop_return_trips API expects a cudf.Series of bool. The current implementation passes integers (1), relying on implicit casting which may vary by backend.

Vulnerable Code:

drop_return = [1] * vehicle_num  # Should be True
drop_return = cudf.Series(drop_return)
new_d.set_drop_return_trips(drop_return)

Suggested Fix:

drop_return = cudf.Series([True] * vehicle_num)


Environment
  • File: python/cuopt/routing.py
  • Function: construct_rerouting_model
Impact
  • Issue #1 causes incorrect capacity constraints to be passed to the solver, potentially leading to invalid routing results without warning.
  • Issue #2 & #3 cause runtime crashes depending on input configuration.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.