#23090·llama_index

[Bug]: Memory truncates highest-priority memory blocks first

Author: Harsh23KashyapCreated Sep 17, 2026Updated Sep 17, 2026

Bug Description

When the long-term memory blocks plus the short-term chat history exceed token_limit, Memory._truncate_memory_blocks drops memory blocks in ascending priority order. That means the block with priority=1 is truncated first and the block with priority=2 survives.

This is the opposite of the documented semantics. The priority field is described as "Priority of this memory block (0 = never truncate, 1 = highest priority, etc.)", and the memory docs example assigns FactExtractionMemoryBlock priority=1 and VectorMemoryBlock priority=2. With the current sort order, the condensed extracted facts are dropped before the bulk raw retrieval batches, which defeats the point of the priority setting.

Version

llama-index-core latest (main)

Steps to Reproduce

import asyncio
from llama_index.core.memory import Memory
from llama_index.core.memory.memory_blocks.static import StaticMemoryBlock

async def main():
    facts = StaticMemoryBlock(name="facts", static_content="important fact " * 20, priority=1)
    vector = StaticMemoryBlock(name="vector", static_content="retrieved chunk " * 20, priority=2)

    memory = Memory.from_defaults(token_limit=60, memory_blocks=[facts, vector])
    msgs = await memory.aget()
    text = str(msgs)
    print("priority=1 (facts) kept:", "important fact" in text)
    print("priority=2 (vector) kept:", "retrieved chunk" in text)

asyncio.run(main())

Output:

priority=1 (facts) kept: False
priority=2 (vector) kept: True

Expected behavior

The lower-priority block (priority=2, the vector retrieval batches) should be truncated first, and the highest-priority block (priority=1, the extracted facts) should survive.

Root cause

Both truncation loops in _truncate_memory_blocks use sorted(self.memory_blocks, key=lambda x: x.priority) (ascending), so the smallest priority number is truncated first. Sorting in descending order truncates the least important blocks first, matching the field description and the docs example. Blocks with priority=0 are still skipped entirely.