kubeflow / kubeflow/sdk

fix(trainer): `get_script_for_python_packages` raises `IndexError` when `pip_index_urls` is empty

Open
#665 1 comment 0 reactions 1 assignee Claimed by @vishalmore90 View on GitHub
Dominant language
Python
Stars
148
Forks
262
Avg merge
1d 2h
Merged PRs (30d)
1

Description

### What happened?

In [`kubeflow/trainer/backends/kubernetes/utils.py`](file:///c:/Users/Vishal/Code_File/Repo%20Folder/sdk/kubeflow/trainer/backends/kubernetes/utils.py#L289-L294), the utility function `get_script_for_python_packages` constructs the pip install options by directly indexing `pip_index_urls[0]`:

```python
# first url will be the index-url.
options = [f"--index-url {shlex.quote(pip_index_urls[0])}"]
options.extend(
f"--extra-index-url {shlex.quote(extra_index_url)}"
for extra_index_url in pip_index_urls[1:]
)
options_str = " ".join(options)
```

When a user defines a `CustomTrainer` with `packages_to_install` specified but sets `pip_index_urls=[]` (an empty list), `get_script_for_python_packages` is invoked during `get_command_using_train_func` ([`utils.py#L388-L393`](file:///c:/Users/Vishal/Code_File/Repo%20Folder/sdk/kubeflow/trainer/backends/kubernetes/utils.py#L388-L393)).

Because `pip_index_urls` is empty, evaluating `pip_index_urls[0]` causes an uncaught runtime exception:

```text
IndexError: list index out of range
```

#### Reproduction Code Example

```python
from kubeflow.trainer import TrainerClient
from kubeflow.trainer.types import CustomTrainer

def train_fn():
import numpy as np
print("Training...", np.__version__)

trainer = CustomTrainer(
func=train_fn,
packages_to_install=["numpy"],
pip_index_urls=[], # Empty list to rely on default pip configuration
)

# Throws IndexError: list index out of range when building trainer CR command
client = TrainerClient()
client.train(trainer=trainer)
```

---

### What did you expect to happen?

`get_script_for_python_packages` should safely check if `pip_index_urls` contains elements before accessing `pip_index_urls[0]`. If `pip_index_urls` is an empty list `[]`, it should not append any `--index-url` or `--extra-index-url` flags to options, allowing pip to proceed with standard default index behavior without throwing an unhandled `IndexError`.

Proposed fix in [`kubeflow/trainer/backends/kubernetes/utils.py`](file:///c:/Users/Vishal/Code_File/Repo%20Folder/sdk/kubeflow/trainer/backends/kubernetes/utils.py#L289-L295):

```python
options = []
if pip_index_urls:
options.append(f"--index-url {shlex.quote(pip_index_urls[0])}")
options.extend(
f"--extra-index-url {shlex.quote(extra_index_url)}"
for extra_index_url in pip_index_urls[1:]
)
options_str = " ".join(options)
```

---

### Environment

Kubernetes version:

```bash
$ kubectl version
Client Version: v1.30.0
```

Kubeflow Trainer version:

```bash
$ kubectl get pods -n kubeflow -l app.kubernetes.io/name=trainer -o jsonpath="{.items[*].spec.containers[*].image}"
ghcr.io/kubeflow/trainer-controller:v1.0.0
```

Kubeflow Python SDK version:

```bash
$ pip show kubeflow
Name: kubeflow
Version: 0.4.1
```

---

### Impacted by this bug?

Give it a 👍 We prioritize the issues with most 👍

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.