From d3777b077967bfb4b6d677aaed14d8ba769f8746 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <41898282+claude[bot]@users.noreply.github.com> Date: Wed, 15 Apr 2026 11:33:12 +0000 Subject: [PATCH] fix(core): default fastembed cache to ~/.basic-memory/fastembed_cache FastEmbed's own default of /tmp/fastembed_cache is ephemeral in sandboxed runtimes like Codex CLI where /tmp is wiped between invocations, causing ONNXRuntimeError: NO_SUCHFILE on every subsequent semantic search or sync. Add _default_fastembed_cache_dir() that mirrors the existing data_dir_path logic (honors BASIC_MEMORY_CONFIG_DIR for isolated test environments) and use it as default_factory for semantic_embedding_cache_dir. The field stays str | None so users can explicitly set null to restore FastEmbed's own default. Fixes #741. Related to #681. Co-authored-by: Drew Cain Signed-off-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> --- src/basic_memory/config.py | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/basic_memory/config.py b/src/basic_memory/config.py index 61eb4556..91aa4dd0 100644 --- a/src/basic_memory/config.py +++ b/src/basic_memory/config.py @@ -50,6 +50,23 @@ def _default_semantic_search_enabled() -> bool: ) +def _default_fastembed_cache_dir() -> str: + """Default FastEmbed model cache to ~/.basic-memory/fastembed_cache. + + FastEmbed's own default is /fastembed_cache (e.g. /tmp/fastembed_cache on + Linux), which is ephemeral in sandboxed runtimes like Codex CLI and can disappear between + invocations, causing ONNXRuntimeError: NO_SUCHFILE on every subsequent run. + + By defaulting to a path inside the Basic Memory data directory we stay consistent with + where other app state lives and ensure the ONNX model survives across sessions. + Honors BASIC_MEMORY_CONFIG_DIR so isolated test environments remain self-contained. + """ + if config_dir := os.getenv("BASIC_MEMORY_CONFIG_DIR"): + return str(Path(config_dir) / "fastembed_cache") + home = os.getenv("HOME", str(Path.home())) + return str(Path(home) / DATA_DIR_NAME / "fastembed_cache") + + @dataclass class ProjectConfig: """Configuration for a specific basic-memory project.""" @@ -221,8 +238,11 @@ class BasicMemoryConfig(BaseSettings): le=16, ) semantic_embedding_cache_dir: str | None = Field( - default=None, - description="Optional cache directory for FastEmbed model artifacts.", + default_factory=_default_fastembed_cache_dir, + description="Cache directory for FastEmbed model artifacts. Defaults to " + "~/.basic-memory/fastembed_cache to avoid FastEmbed's ephemeral /tmp default, " + "which breaks MCP in sandboxed runtimes (e.g. Codex CLI). " + "Set to null to use FastEmbed's own default.", ) semantic_embedding_threads: int | None = Field( default=None,