Repository: UKPLab/sentence-transformers

Issue:
TypeError: 'int' object is not subscriptable when using prompts and output_value=None
Hi, when using prompts, executing `model.encode(texts, output_value=None)` raises the following error:

```
TypeError: 'int' object is not subscriptable.
```

This occurs because `out_features['prompt_length']` is an `int`, but the code attempts to access it using `out_features[name][sent_idx]`, as if it were a subscriptable object like a list or dictionary.

https://github.com/UKPLab/sentence-transformers/blob/03dff58425e0b9c2f52f6f29d51f430d0b60795a/sentence_transformers/SentenceTransformer.py#L633-L640

https://github.com/UKPLab/sentence-transformers/blob/03dff58425e0b9c2f52f6f29d51f430d0b60795a/sentence_transformers/SentenceTransformer.py#L703-L704

Here is minimal code to reproduce the error:

```py
from sentence_transformers import SentenceTransformer

model = SentenceTransformer("microsoft/mpnet-base", prompts={'query': 'query:'}, default_prompt_name='query')
model.encode(['sentence1', 'sentence2'], output_value=None)
```

```
Traceback (most recent call last):
  File "sample.py", line 5, in <module>
    model.encode(['sentence1', 'sentence2'], output_value=None)
  File ".venv/lib/python3.10/site-packages/sentence_transformers/SentenceTransformer.py", line 579, in encode
    row = {name: out_features[name][sent_idx] for name in out_features}
  File ".venv/lib/python3.10/site-packages/sentence_transformers/SentenceTransformer.py", line 579, in <dictcomp>
    row = {name: out_features[name][sent_idx] for name in out_features}
TypeError: 'int' object is not subscriptable
```

I'm using `sentence_transformers-4.0.1`.
Thank you.

Discussion:

Solution patch:
diff --git a/sentence_transformers/SentenceTransformer.py b/sentence_transformers/SentenceTransformer.py
index b65b9c1..79ee0d1 100644
--- a/sentence_transformers/SentenceTransformer.py
+++ b/sentence_transformers/SentenceTransformer.py
@@ -700,9 +700,15 @@ class SentenceTransformer(nn.Sequential, FitMixin, PeftAdapterMixin):
                         embeddings.append(token_emb[0 : last_mask_id + 1])
                 elif output_value is None:  # Return all outputs
                     embeddings = []
-                    for sent_idx in range(len(out_features["sentence_embedding"])):
-                        row = {name: out_features[name][sent_idx] for name in out_features}
-                        embeddings.append(row)
+                    for idx in range(len(out_features["sentence_embedding"])):
+                        batch_item = {}
+                        for name, value in out_features.items():
+                            try:
+                                batch_item[name] = value[idx]
+                            except TypeError:
+                                # Handle non-indexable values (like prompt_length)
+                                batch_item[name] = value
+                        embeddings.append(batch_item)
                 else:  # Sentence embeddings
                     embeddings = out_features[output_value]
                     embeddings = embeddings.detach()


Test patch:
diff --git a/tests/test_sentence_transformer.py b/tests/test_sentence_transformer.py
index f9bef5a..96694cd 100644
--- a/tests/test_sentence_transformer.py
+++ b/tests/test_sentence_transformer.py
@@ -376,6 +376,27 @@ def test_save_load_prompts() -> None:
         assert fresh_model.default_prompt_name == "query"
 
 
+def test_prompt_output_value_None(stsb_bert_tiny_model_reused) -> None:
+    model = stsb_bert_tiny_model_reused
+    outputs = model.encode(
+        ["Text one", "Text two"],
+        prompt="query: ",
+        output_value=None,
+    )
+    assert len(outputs) == 2
+    assert isinstance(outputs, list)
+    expected_keys = {
+        "input_ids",
+        "token_type_ids",
+        "attention_mask",
+        "sentence_embedding",
+        "token_embeddings",
+        "prompt_length",
+    }
+    assert set(outputs[0].keys()) == expected_keys
+    assert set(outputs[1].keys()) == expected_keys
+
+
 @pytest.mark.skipif(not torch.cuda.is_available(), reason="CUDA must be available to test float16 support.")
 def test_load_with_torch_dtype() -> None:
     model = SentenceTransformer("sentence-transformers-testing/stsb-bert-tiny-safetensors")