oraios/serena · error · ValueError
Memory name cannot be absolute or contain empty path segment
Error message
Memory name cannot be absolute or contain empty path segments. Got: {name} What it means
get_memory_file_path rejects absolute memory names and names with empty path segments. Because pathlib discards the base directory when joined with an absolute path (e.g. "/etc/cron.d/backdoor" would resolve to "/etc/cron.d"), an absolute or empty-segment name could let the memory name escape the sandbox, so a ValueError is raised.
Source
Thrown at src/serena/memories/memory_manager.py:184
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"
return self._resolve_memory_path(self._project_memory_dir, parts)
def _check_write_access(self, name: str, is_tool_context: bool) -> None:
# in tool context, memories can be read-only
if is_tool_context and self._is_read_only_memory(name):
raise PermissionError(f"Attempted to write to read_only memory: '{name}')")View on GitHub (pinned to 7fcbca7e62)
Solutions
- Strip leading slashes and collapse duplicate slashes from the memory name before calling the API.
- Pass a relative name like "topic/sub/name"; never an absolute path.
- If you meant to read an actual filesystem path, use read_file with the absolute path, not the memory API.
- Add a pre-call check: reject names where name != posixpath.normpath(name) or name.startswith('/').
Example fix
// before
manager.load_memory("/etc/notes")
// after
manager.load_memory("notes") # relative, no empty segments
# or for real files:
read_file(Path("/etc/notes")) Defensive patterns
Strategy: validation
Validate before calling
import posixpath
if name.startswith("/") or name != posixpath.normpath(name):
raise ValueError(f"memory name must be relative with no empty segments: {name!r}") Type guard
def is_relative_clean_path(name: str) -> bool:
import posixpath
parts = name.split("/")
return not name.startswith("/") and "" not in parts Try / catch
try:
content = manager.load_memory(name)
except ValueError as e:
if "absolute or contain empty path segments" in str(e):
name = "/".join(p for p in name.split("/") if p).lstrip("/")
content = manager.load_memory(name)
else:
raise Prevention
- Always store/derive memory names relative to the memories dir
- Collapse duplicate slashes and strip leading/trailing slashes before calls
- Use read_file for actual absolute filesystem paths
When it happens
Trigger: Calling get_memory_file_path (or any memory API) with a name starting with '/' (producing an empty first segment after split) or containing '//' / a trailing '/' — e.g. "/etc/notes", "topic//sub", or "notes/".
Common situations: Building memory names by concatenating path strings without normalization; LLM agents passing absolute filesystem paths as memory names; template strings with stray slashes; Windows backslashes are converted to '/' by _sanitize_name, so '\\server\\share' style inputs can surface here.
Related errors
- Memory name resolves outside the memories directory. Got: {'
- Memory name cannot contain '..' segments. Got: {name}
- 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/44ad3a0d20ff121f.
Report an issue: GitHub.