Repository navigation
FastEmbed cache defaults to /tmp/fastembed_cache — breaks MCP in sandboxed runtimes (Codex, ephemeral /tmp) #741
Description
Summary
When semantic_embedding_cache_dir is unset (the default), FastEmbed falls back to its own default of <system temp dir>/fastembed_cache — on Linux this resolves to /tmp/fastembed_cache. In sandboxed MCP runtimes like Codex CLI, /tmp is ephemeral (wiped between invocations) or otherwise unreliable, so the ONNX model either fails to download or disappears between runs, and every semantic search raises ONNXRuntimeError : NO_SUCHFILE.
Stack trace
# Search Failed
Error searching for 'FrameAnnotation video_id object_id':
[ONNXRuntimeError] : 3 : NO_SUCHFILE : Load model from
/tmp/fastembed_cache/models--qdrant--bge-small-en-v1.5-onnx-q/
snapshots/52398278842ec682c6f32300af41344b1c0b0bb2/
model_optimized.onnx failed: Load model
/tmp/fastembed_cache/models--qdrant--bge-small-en-v1.5-onnx-q/
snapshots/523...
Root cause
FastEmbedEmbeddingProvider only passes cache_dir to TextEmbedding(...) when semantic_embedding_cache_dir is explicitly set (see src/basic_memory/repository/fastembed_provider.py:75-85). When it's None, FastEmbed's own default kicks in:
cache_dir(str, optional): The path to the cache directory. Can be set using theFASTEMBED_CACHE_PATHenv variable. Defaults tofastembed_cachein the system's temp directory.
—fastembed/text/onnx_embedding.py
Basic Memory's config default:
# src/basic_memory/config.py
semantic_embedding_cache_dir: str | None = Field(
default=None,
description=\"Optional cache directory for FastEmbed model artifacts.\",
)Why this surfaces now
Semantic search has been default-on for a while, but FastEmbed was only loaded lazily on first semantic query, so users whose environments didn't tolerate /tmp/fastembed_cache could silently avoid it. Recent changes make FastEmbed load much more eagerly:
- e846ae8 — "fix: semantic embeddings not generated on fresh DB or upgrade" — added batch embedding generation at the end of every sync, so any new/modified file triggers a FastEmbed load during startup sync.
- 540da41 — "perf(sync): batch file indexing in core (perf(sync): batch file indexing in core #726)" — batch indexer keeps embeddings on the sync path.
- 7945c1e — "perf(core): speed up vector sync and tune fastembed defaults (perf(core): speed up vector sync and tune fastembed defaults #731)" — tuned defaults further, also on the sync path.
Combined with a runtime (Codex) that wipes /tmp between sessions, the model directory disappears and every subsequent ONNX load fails with NO_SUCHFILE.
Proposed fix
Default semantic_embedding_cache_dir to a stable, user-writable path under the Basic Memory config/data dir instead of relying on the system temp dir. Something like:
def _default_fastembed_cache_dir() -> str:
# Stable across runs, user-writable, honors XDG on Linux.
return str(Path(platformdirs.user_cache_dir(\"basic-memory\")) / \"fastembed\")
semantic_embedding_cache_dir: str = Field(
default_factory=_default_fastembed_cache_dir,
description=\"Cache directory for FastEmbed model artifacts.\",
)Alternative / additional hardening:
- Respect
FASTEMBED_CACHE_PATHif set in the environment (FastEmbed already does, but we should document it). - At startup, if the configured cache dir isn't writable, log a clear warning and fall back to
~/.basic-memory/fastembed_cache.
Workarounds
- Set
FASTEMBED_CACHE_PATH=~/.cache/fastembedin the MCP server's env. - Set
semantic_embedding_cache_dirin~/.basic-memory/config.jsonto a stable user-writable path. - As a last resort, disable semantic search:
BASIC_MEMORY_SEMANTIC_SEARCH_ENABLED=false.
Reproduction
- Start
basic-memory mcpin a runtime where/tmpis ephemeral (Codex CLI sandbox, or simplyrm -rf /tmp/fastembed_cachebetween runs on Linux). - Trigger any sync or semantic search.
- Observe
ONNXRuntimeError : NO_SUCHFILEreferencing/tmp/fastembed_cache/....
Activity
claude commentedon Apr 15, 2026
Claude finished @groksrc's task in 2m 48s —— View job •
claude/issue-741-20260415-1130• Create PR ➔Triage & Fix: FastEmbed cache defaults to /tmp
Type: Bug | Priority: High | Component: MCP, Database | Complexity: Simple
Duplicate note: Related to #681 (same root cause; this issue adds a Codex CLI repro + detailed stack trace).
config.py,fastembed_provider.py,embedding_provider_factory.py)buglabelconfig.pyWhat was done
Added
_default_fastembed_cache_dir()insrc/basic_memory/config.pythat returns~/.basic-memory/fastembed_cache(or$BASIC_MEMORY_CONFIG_DIR/fastembed_cachein isolated environments), and wired it as thedefault_factoryforsemantic_embedding_cache_dir.Root cause:
semantic_embedding_cache_dirdefaulted toNone, which let FastEmbed fall back to its own default of/tmp/fastembed_cache. In sandboxed runtimes where/tmpis wiped between invocations (e.g. Codex CLI), the cached ONNX model disappears and every semantic search raisesONNXRuntimeError: NO_SUCHFILE.Fix summary:
~/.basic-memory/fastembed_cache— stable across sessions, consistent with where other Basic Memory state livesstr | None— users can explicitly setnullto opt back into FastEmbed's own defaultBASIC_MEMORY_CONFIG_DIRso isolated test environments remain self-containedembedding_provider_factory.pyunchanged — the existingis not Noneguard already handles thenullescape hatch correctly|
fix(core): default fastembed cache to ~/.basic-memory/fastembed_cache
fix(core): resolve FastEmbed cache under data dir instead of /tmp
feat(search): add optional cross-encoder reranker stage