Hacktoberfest 2026: die Issues, die Maintainer für den Oktober markiert haben – offen und einsteigerfreundlich. Hacktoberfest-Issues durchsuchen

BUG: MemoryInterface.get_request_from_response fails with IndexError for non-zero starting sequence or sequence gaps

Geschlossen
#3,189 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Maintainer antworten meist innerhalb von 2 Tagen

@RohithPariki arbeitet bereits daran.

Seit 13.10.2026.

  • #3190 von @RohithPariki — offen

Bewertung

Schwierigkeit
2/5
Geschätzter Aufwand
1-3 Stunden
Anfängerfreundlichkeit
25/100
Issue-Typ
Bug
Klarheit
Klar beschrieben
Aktivitätsstatus
Aktiv
Tech-Stack
python
Bereich
databases

Rechercherichtung

The bug is in _execute_get_request_from_response in pyrit/memory/memory_interface.py, which indexes the conversation list by response.sequence - 1. Read _execute_get_conversation_messages to see how messages are ordered, then reproduce with the SQLite script in the issue. Pull request #3190 is already open against this issue, so check it before starting a new fix. Done means the method returns the message with the closest lower sequence, or raises a clear error when none exists.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Beschreibung

Describe the bug

In pyrit/memory/memory_interface.py, MemoryInterface._execute_get_request_from_response retrieves the request that produced a given assistant response:

    def _execute_get_request_from_response(self, *, response: Message) -> Message:
        if response.api_role != "assistant":
            raise ValueError("The provided request is not a response (role must be 'assistant').")
        if response.sequence < 1:
            raise ValueError("The provided request does not have a preceding request (sequence < 1).")

        conversation = self._dispatch_memory_operation(
            "get_conversation_messages",
            self._execute_get_conversation_messages,
            conversation_id=response.conversation_id,
        )
        return conversation[response.sequence - 1]

The method treats response.sequence - 1 as a 0-based list index into conversation. However, get_conversation_messages returns messages ordered by sequence (sorted(conversation_by_sequence.keys())), where list index corresponds to sequence number only if the conversation started at sequence 0 and contains no sequence gaps.

Whenever:

  1. A conversation starts at a non-zero sequence (e.g. using starting_sequence in SeedPrompt.from_messages or SimulatedConversationAttack), or
  2. A conversation contains sequence gaps (e.g. after pruning or retries where pieces were deleted),

calling get_request_from_response (or get_request_from_response_async, or DecodingScorer which invokes this method) raises:
IndexError: list index out of range (or returns the wrong message if the index exists but does not align).

Steps/Code to Reproduce
import asyncio
from uuid import uuid4
from pyrit.memory import SQLiteMemory
from pyrit.models import MessagePiece

async def test_reproduce():
    memory = SQLiteMemory(db_path=":memory:")
    conversation_id = str(uuid4())

    # Create a conversation with starting_sequence=10
    pieces = [
        MessagePiece(
            role="user",
            original_value="What is the capital of France?",
            conversation_id=conversation_id,
            sequence=10,
        ),
        MessagePiece(
            role="assistant",
            original_value="Paris.",
            conversation_id=conversation_id,
            sequence=11,
        ),
    ]
    await memory.add_message_pieces_to_memory_async(message_pieces=pieces)

    conversation = await memory.get_conversation_messages_async(conversation_id=conversation_id)
    response = conversation[1]  # sequence=11

    # Attempt to retrieve the request that produced the response
    await memory.get_request_from_response_async(response=response)

asyncio.run(test_reproduce())
Expected Results

get_request_from_response_async returns the message immediately preceding the response in the conversation timeline (Message(role='user', sequence=10, ...)).

Actual Results
Traceback (most recent call last):
  ...
  File "pyrit/memory/memory_interface.py", line 3041, in _execute_get_request_from_response
    return conversation[response.sequence - 1]
           ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^
IndexError: list index out of range
Suggested Fix

Instead of assuming conversation index equals sequence - 1, locate the preceding message in conversation with sequence < response.sequence:

        conversation = self._dispatch_memory_operation(
            "get_conversation_messages",
            self._execute_get_conversation_messages,
            conversation_id=response.conversation_id,
        )
        preceding_messages = [msg for msg in conversation if msg.sequence < response.sequence]
        if not preceding_messages:
            raise ValueError(
                f"The provided request does not have a preceding request in conversation '{response.conversation_id}'."
            )
        return preceding_messages[-1]
Vorherrschende Sprache
Python
Sterne
4.6k
Forks
944
Ø Merge
2 T. 17 Std.
Gemergte PRs (30 T.)
328

Entwicklungsumgebung

In Codespaces öffnen

Startet den Dev-Container des Projekts im Browser, mit Ihrem eigenen GitHub-Konto.

  • Kein Dockerfile und keine Docker-Compose-Datei
  • Hat eine Pull-Request-Vorlage
  • Kein Beitragsleitfaden

Erste Schritte

  1. Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
  3. Forken Sie das Repository und arbeiten Sie in einem Branch.
  4. Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.

Mehr aus microsoft/PyRIT

Alle Issues in microsoft/PyRIT

Ähnliche Issues

Weitere Issues zu Python

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.