Skip to content

FastEmbed cache defaults to /tmp/fastembed_cache — breaks MCP in sandboxed runtimes (Codex, ephemeral /tmp) #741

Closed

Description

@groksrc

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 the FASTEMBED_CACHE_PATH env variable. Defaults to fastembed_cache in 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:

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_PATH if 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/fastembed in the MCP server's env.
  • Set semantic_embedding_cache_dir in ~/.basic-memory/config.json to a stable user-writable path.
  • As a last resort, disable semantic search: BASIC_MEMORY_SEMANTIC_SEARCH_ENABLED=false.

Reproduction

  1. Start basic-memory mcp in a runtime where /tmp is ephemeral (Codex CLI sandbox, or simply rm -rf /tmp/fastembed_cache between runs on Linux).
  2. Trigger any sync or semantic search.
  3. Observe ONNXRuntimeError : NO_SUCHFILE referencing /tmp/fastembed_cache/....

Activity

  1. claude commented on Apr 15, 2026

    @claude
    Contributor

    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).

    What was done

    Added _default_fastembed_cache_dir() in src/basic_memory/config.py that returns ~/.basic-memory/fastembed_cache (or $BASIC_MEMORY_CONFIG_DIR/fastembed_cache in isolated environments), and wired it as the default_factory for semantic_embedding_cache_dir.

    Root cause: semantic_embedding_cache_dir defaulted to None, which let FastEmbed fall back to its own default of /tmp/fastembed_cache. In sandboxed runtimes where /tmp is wiped between invocations (e.g. Codex CLI), the cached ONNX model disappears and every semantic search raises ONNXRuntimeError: NO_SUCHFILE.

    Fix summary:

    • New default: ~/.basic-memory/fastembed_cache — stable across sessions, consistent with where other Basic Memory state lives
    • Type stays str | None — users can explicitly set null to opt back into FastEmbed's own default
    • Honors BASIC_MEMORY_CONFIG_DIR so isolated test environments remain self-contained
    • embedding_provider_factory.py unchanged — the existing is not None guard already handles the null escape hatch correctly

    |

  2. added a commit that references this issue on Apr 15, 2026
    d3777b0
  3. added a commit that references this issue on Apr 15, 2026
    1a8fbd5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions