{"record":{"id":"fb3560f71286760d","repo":"oraios/serena","slug":"bare-self-global-topic-is-not-a-valid-memory-n","errorCode":null,"errorMessage":"Bare \"{self.GLOBAL_TOPIC}\" is not a valid memory name. Use \"{self.GLOBAL_TOPIC}/<name>\" to address a global memory.","messagePattern":"Bare \"(.+?)\" is not a valid memory name\\. Use \"(.+?)/<name>\" to address a global memory\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/serena/memories/memory_manager.py","lineNumber":188,"sourceCode":"        subdir.mkdir(parents=True, exist_ok=True)\n        return candidate\n\n    def get_memory_file_path(self, name: str) -> Path:\n        name = self._sanitize_name(name)\n        parts = name.split(\"/\")\n\n        if \"..\" in parts:\n            raise ValueError(f\"Memory name cannot contain '..' segments. Got: {name}\")\n\n        # Reject absolute names and empty path segments: pathlib discards the base directory when\n        # joined with an absolute path (e.g. \"/etc/cron.d/backdoor\" would reset to \"/etc/cron.d\"),\n        # letting a memory name escape the sandbox. A leading \"/\" produces an empty first segment.\n        if os.path.isabs(name) or \"\" in parts:\n            raise ValueError(f\"Memory name cannot be absolute or contain empty path segments. Got: {name}\")\n\n        if self._is_global(name):\n            if name == self.GLOBAL_TOPIC:\n                raise ValueError(\n                    f'Bare \"{self.GLOBAL_TOPIC}\" is not a valid memory name. Use \"{self.GLOBAL_TOPIC}/<name>\" to address a global memory.'\n                )\n            # Strip \"global/\" prefix and resolve against global dir\n            sub_name = name[len(self.GLOBAL_TOPIC) + 1 :]\n            return self._resolve_memory_path(self._global_memory_dir, sub_name.split(\"/\"))\n\n        # Project-local memory\n        assert self._project_memory_dir is not None, \"Project dir was not passed at initialization\"\n        return self._resolve_memory_path(self._project_memory_dir, parts)\n\n    def _check_write_access(self, name: str, is_tool_context: bool) -> None:\n        # in tool context, memories can be read-only\n        if is_tool_context and self._is_read_only_memory(name):\n            raise PermissionError(f\"Attempted to write to read_only memory: '{name}')\")\n\n    def load_memory(self, name: str) -> str:\n        name = self._sanitize_name(name)\n        self._check_not_ignored(name)","sourceCodeStart":170,"sourceCodeEnd":206,"githubUrl":"https://github.com/oraios/serena/blob/7fcbca7e62555ec2287ddb2f083caee805848ea6/src/serena/memories/memory_manager.py#L170-L206","documentation":"The reserved topic 'global' addresses global (cross-project) memories, but the bare name 'global' alone is not a memory. get_memory_file_path raises ValueError telling you to use the form 'global/<name>'. Global memories resolve against the global memories directory with the prefix stripped.","triggerScenarios":"Calling load_memory/save_memory/etc. with exactly \"global\" (after _sanitize_name strips 'mem:' and '.md'), instead of \"global/<memory-name>\".","commonSituations":"Agents listing memories and mistaking the 'global' topic directory for a memory item; users trying to read all global memories at once by the topic name; scripts that join a topic prefix without appending a memory name.","solutions":["Append the actual memory name: use \"global/<name>\" instead of \"global\".","To see available global memories, enumerate files in the global memories directory (list_memories output shows global/<name> entries).","If you want a project memory, drop the 'global' prefix entirely and use a plain name.","Wrap the call defensively and treat the error message's suggested format as the corrected name."],"exampleFix":"// before\ncontent = manager.load_memory(\"global\")\n// after\ncontent = manager.load_memory(\"global/coding_conventions\")","handlingStrategy":"validation","validationCode":"if name == \"global\":\n    raise ValueError('use \"global/<memory-name>\", not the bare topic \"global\"')","typeGuard":"def is_valid_memory_name(name: str) -> bool:\n    return name != \"global\" and bool(name)","tryCatchPattern":"try:\n    content = manager.load_memory(name)\nexcept ValueError as e:\n    if \"not a valid memory name\" in str(e):\n        names = manager.list_memories()\n        content = next(manager.load_memory(n) for n in names if n.startswith(\"global/\"))\n    else:\n        raise","preventionTips":["Never treat the 'global' topic itself as a memory; always append '/<name>'","Enumerate global memories via list_memories instead of guessing the topic name","Validate names against 'global/...' format when working with global scope"],"tags":["python","memory","naming","validation"],"backgroundTag":"bare-topic-not-valid-memory-name","analyzedSha":"7fcbca7e62555ec2287ddb2f083caee805848ea6","analyzedAt":"2026-08-29T00:04:09.619Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}