Memory.update drops root_scope when moving a memory
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 58.8k
- Forks
- 8.5k
- Avg merge
- 1d 15h
- Merged PRs (30d)
- 109
Description
Description
Moving a memory with Memory.update(record_id, scope=...) drops the configured root_scope prefix. The update succeeds, but subsequent recall and listing through the same Memory instance cannot find the moved record.
For example, with root_scope="/crew/research", saving under /original creates /crew/research/original. Updating its scope to /renamed currently stores /renamed instead of /crew/research/renamed.
Steps to Reproduce
Run the example below against current main. It uses an embedded LanceDB database and fixed embeddings; no model or API calls are needed.
Expected behavior
update(..., scope="/renamed") should interpret the scope relative to root_scope, consistently with remember, recall, and list_records. The updated record should remain retrievable through the same memory instance.
Screenshots/Code snippets
from tempfile import TemporaryDirectory
from unittest.mock import MagicMock
from crewai.memory import Memory
with TemporaryDirectory() as path:
memory = Memory(
storage=path,
root_scope="/crew/research",
llm=MagicMock(),
embedder=lambda texts: [[0.1, 0.2, 0.3] for _ in texts],
)
try:
record = memory.remember(
"A remembered fact",
scope="/original",
categories=["test"],
importance=0.7,
)
updated = memory.update(record.id, scope="/renamed")
print(updated.scope) # /renamed
print(memory.list_records()) # []
print(memory.recall("A remembered fact", depth="shallow")) # []
finally:
memory.close()
Operating System
macOS 15.5, Apple Silicon
Python Version
3.12.13
crewAI Version
1.15.22, main at 3831e8b6c86f78cb3cde18ebf7be0d197b958f0e
crewAI Tools Version
1.15.22 (not used in this reproduction)
Virtual Environment
Venv, managed by uv from the repository lockfile.
Evidence
The standalone example prints /renamed, then two empty lists on the unmodified base. Three regression cases (a new inner scope, a missing leading slash, and moving to /) fail on that base; four compatibility/read-only controls pass. After resolving the destination against root_scope, the complete memory test directory passes: 141 passed, 19 skipped.
Possible Solution
Apply join_scope_paths(self.root_scope, scope) when a new scope is provided and root_scope is set. Leave omitted scopes and unrooted memories unchanged.
Additional context
This report and the proposed fix were prepared with AI assistance. The repository requires the llm-generated label.
I requested the llm-generated label when opening this issue, but GitHub did not apply it. An explicit label update was denied because my account lacks permission to add labels in this repository. Could a maintainer apply the required label?
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the Python Memory.update entry point and the existing memory test directory, then run the reported regression cases for rooted scope changes, missing leading slashes, and moving to /. Done means explicit scopes preserve root_scope while omitted scopes and unrooted memories remain unchanged, with the complete memory test directory passing.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- database
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 76/100