Skip to content

Bug Report: get_last_k_turns() returns messages in reversed order within each turn #253

Description

@ecoonomykim

Bug Report: get_last_k_turns() returns messages in reversed order within each turn

Reporter: Amazon Employee (not a team member of AgentCore SDK, reporting issue only)

Description

get_last_k_turns() returns turns with messages in reversed order (ASSISTANT before USER) instead of chronological order (USER before ASSISTANT). This contradicts the docstring which states "A turn typically consists of a user message followed by assistant response(s)."

Environment

  • OS: macOS
  • Python version: 3.12
  • SDK version: 1.2.0, 1.2.1 (tested both - bug persists)
  • AWS Region: ap-northeast-2

Steps to Reproduce

from bedrock_agentcore.memory import MemoryClient, MemorySessionManager

memory_client = MemoryClient(region_name="ap-northeast-2")
session_manager = MemorySessionManager(
    memory_id="mem-xxxxxxxx",
    region_name="ap-northeast-2",
)

# Create events in chronological order
# Event 1: USER "Hello"
# Event 2: ASSISTANT "Hi there!"
# Event 3: USER "What's the weather?"
# Event 4: ASSISTANT [toolUse: get_weather]
# Event 5: USER [toolResult: sunny]
# Event 6: ASSISTANT "It's sunny today"

# Get last k turns
turns = session_manager.get_last_k_turns(
    actor_id="user_001",
    session_id="session_001",
    k=10
)

print(turns)

Expected Behavior

Each turn should have messages in chronological order (USER first, then ASSISTANT):

[
    [{'role': 'USER', 'content': ...}, {'role': 'ASSISTANT', 'content': ...}],
    [{'role': 'USER', 'content': ...}, {'role': 'ASSISTANT', 'content': ...}],
    ...
]

Actual Behavior

Each turn has messages in reversed order (ASSISTANT first, then USER):

[
    [{'role': 'ASSISTANT', 'content': "서울역[1호선]으로 안내를..."}],  # Turn with only ASSISTANT
    [{'role': 'USER', 'content': ...toolResult...}, {'role': 'ASSISTANT', 'content': ...toolUse...}],  # Reversed!
    [{'role': 'USER', 'content': "2번"}, {'role': 'ASSISTANT', 'content': "서울역 5곳이에요..."}],  # Looks correct but paired with PREVIOUS assistant response
    ...
]

Root Cause Analysis

Looking at the SDK source code in client.py:

def get_last_k_turns(self, ...):
    # ...
    response = self.gmdp_client.list_events(**params)  # Returns events in reverse chronological order (newest first)
    events = response.get("events", [])
    
    for event in events:  # Iterates in reverse order without sorting
        # ...
        if role == Role.USER.value and current_turn:
            turns.append(current_turn)
            current_turn = []
        current_turn.append(payload_item["conversational"])

The issue is that list_events API returns events in reverse chronological order (newest first), but the SDK processes them without sorting to chronological order first.

Suggested Fix

Sort events by eventTimestamp before processing:

def get_last_k_turns(self, ...):
    # ... fetch events ...
    
    # Sort events chronologically before processing
    all_events = sorted(all_events, key=lambda e: e.get('eventTimestamp', ''))
    
    # Then process turns...

Or reverse the events list before iteration:

for event in reversed(events):  # Process oldest to newest

Impact

This bug affects any application that relies on get_last_k_turns() to retrieve conversation history for:

  • Passing to LLM as context (messages appear in wrong order)
  • Displaying conversation history to users
  • Analyzing conversation flow

Workaround

Currently using list_events() and manually sorting/grouping:

events = session_manager.list_events(actor_id, session_id)
events_sorted = sorted(events, key=lambda e: e['eventTimestamp'])
# Manual turn grouping...

Related

Update Log

2026-02-05: Tested with SDK 1.2.1

Bug still persists in version 1.2.1. Test results:

SDK Version: 1.2.1

============================================================
각 턴의 메시지 순서 확인:
============================================================
Turn 1: ['ASSISTANT']           # ← Only ASSISTANT, no USER
Turn 2: ['USER', 'ASSISTANT']   # ← Looks correct but actually misaligned
Turn 3: ['USER', 'ASSISTANT']
Turn 4: ['USER', 'ASSISTANT']
Turn 5: ['USER', 'ASSISTANT']

The issue is that Turn 1 contains only ASSISTANT (orphaned from its USER), and subsequent turns pair the PREVIOUS assistant response with the CURRENT user message - the entire conversation is shifted by one position.

Metadata

Metadata

Assignees

No one assigned

    Labels

    memoryRelated to agentcore memory

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions