oraios/serena · error · ValueError
Memory name cannot contain '..' segments. Got: {name}
Error message
Memory name cannot contain '..' segments. Got: {name} What it means
get_memory_file_path explicitly rejects memory names containing '..' segments with a ValueError before resolving the path. This is a path-traversal guard: '..' would let a memory name address files outside the .serena/memories sandbox.
Source
Thrown at src/serena/memories/memory_manager.py:178
resolution): directory symlinks placed inside the memories folder are a supported way to
share memories (e.g. a monorepo symlinking each submodule's memory dir), and those must
keep resolving to their targets at I/O time.
"""
filename = f"{parts[-1]}.md"
subdir = base_dir if len(parts) == 1 else base_dir.joinpath(*parts[:-1])
candidate = subdir / filename
base_norm = Path(os.path.normpath(base_dir))
if not Path(os.path.normpath(candidate)).is_relative_to(base_norm):
raise ValueError(f"Memory name resolves outside the memories directory. Got: {'/'.join(parts)}")
subdir.mkdir(parents=True, exist_ok=True)
return candidate
def get_memory_file_path(self, name: str) -> Path:
name = self._sanitize_name(name)
parts = name.split("/")
if ".." in parts:
raise ValueError(f"Memory name cannot contain '..' segments. Got: {name}")
# Reject absolute names and empty path segments: pathlib discards the base directory when
# joined with an absolute path (e.g. "/etc/cron.d/backdoor" would reset to "/etc/cron.d"),
# letting a memory name escape the sandbox. A leading "/" produces an empty first segment.
if os.path.isabs(name) or "" in parts:
raise ValueError(f"Memory name cannot be absolute or contain empty path segments. Got: {name}")
if self._is_global(name):
if name == self.GLOBAL_TOPIC:
raise ValueError(
f'Bare "{self.GLOBAL_TOPIC}" is not a valid memory name. Use "{self.GLOBAL_TOPIC}/<name>" to address a global memory.'
)
# Strip "global/" prefix and resolve against global dir
sub_name = name[len(self.GLOBAL_TOPIC) + 1 :]
return self._resolve_memory_path(self._global_memory_dir, sub_name.split("/"))
# Project-local memory
assert self._project_memory_dir is not None, "Project dir was not passed at initialization"View on GitHub (pinned to 7fcbca7e62)
Solutions
- Remove '..' segments and address the memory by its name within the memories directory.
- If the target file lives outside memories, use the read_file tool on its absolute path instead.
- Validate or normalize names from untrusted sources before passing them to memory APIs (reject any name containing '..').
- Note names are sanitized first ('mem:' prefix, '.md' suffix, OS separators removed) — after sanitization '..' still means a literal dot-dot segment and is invalid.
Example fix
// before
manager.load_memory("../secrets/keys")
// after
manager.load_memory("secrets/keys") # stays inside .serena/memories Defensive patterns
Strategy: validation
Validate before calling
if ".." in name.split("/"):
raise ValueError(f"memory name must not contain '..': {name!r}") Type guard
def has_no_dotdot(name: str) -> bool:
return ".." not in name.split("/") Try / catch
try:
content = manager.load_memory(name)
except ValueError as e:
if "'..'" in str(e):
log.warning("traversal blocked for %r; use read_file for external files", name)
else:
raise Prevention
- Reject or normalize '..' in names at your API boundary
- For files outside memories, use read_file on absolute paths, never memory names
- Audit LLM-generated names before passing them to memory APIs
When it happens
Trigger: Calling load_memory, save_memory, delete_memory, move_memory, edit_memory, or get_memory_file_path with a name like "../config" or "topic/../../secrets" (the '..' check precedes the absolute/empty-segment check).
Common situations: LLM agents hallucinating relative-style memory names; users trying to read files outside the project memories dir through the memory tool; scripting that interpolates user input into memory names.
Related errors
- Memory name resolves outside the memories directory. Got: {'
- Memory name cannot be absolute or contain empty path segment
- Cannot edit external file: {relative_path}
- Cannot use both fixed_tools and excluded_tools/included_opti
- Unknown language backend '{backend_str}': valid values are {
AI-assisted analysis of oraios/serena@7fcbca7e62 (2026-08-29).
Data as JSON: /api/errors/381047574a2b111f.
Report an issue: GitHub.