xai-org/x-algorithm · error · anyhow::Error

EmbeddingCache: no database in {}

Error message

EmbeddingCache: no database in {}

What it means

Raised by EmbeddingCache::open when the LMDB environment at lmdb_path opens successfully but contains no named database — the file exists but has no data inside it. The cache cannot be initialized because there is nothing to read.

Source

Thrown at phoenix/crates/serving/xai-recsys-mm-server/src/embedding_cache.rs:280

        lmdb_path: &Path,
        data_path: &Path,
        ttl: std::time::Duration,
    ) -> anyhow::Result<Self> {
        let data_mdb = lmdb_path.join("data.mdb");
        let map_size = std::fs::metadata(&data_mdb)
            .map(|m| m.len() as usize)
            .unwrap_or(0)
            .max(1024 * 1024);

        let env = unsafe {
            heed::EnvOpenOptions::new()
                .map_size(map_size)
                .max_readers(1024)
                .open(lmdb_path)?
        };
        let rtxn = env.read_txn()?;
        let db = env.open_database(&rtxn, None)?.ok_or_else(|| {
            anyhow::anyhow!("EmbeddingCache: no database in {}", lmdb_path.display())
        })?;
        let emb_dim = db
            .get(&rtxn, &LMDB_META_KEY_EMB_DIM)?
            .ok_or_else(|| anyhow::anyhow!("EmbeddingCache: missing emb_dim metadata"))?
            as usize;
        rtxn.commit()?;

        let file = OpenOptions::new().read(true).write(true).open(data_path)?;
        let mmap = unsafe { MmapMut::map_mut(&file)? };
        let slot_size = SLOT_HEADER_SIZE + emb_dim * std::mem::size_of::<f16>();
        let capacity = (mmap.len() - HEADER_SIZE) / slot_size;

        log::info!(
            "EmbeddingCache: opened lmdb={} data={} (capacity={}, emb_dim={})",
            lmdb_path.display(),
            data_path.display(),
            capacity,
            emb_dim,

View on GitHub (pinned to 24c60942c5)

Solutions

  1. Point lmdb_path at a database produced by EmbeddingCache::create
  2. If the cache should be built fresh, call create() instead of open()
  3. If the file is corrupted, delete it and regenerate via create()
  4. Add a preflight check that the path is a non-empty, valid LMDB file before calling open

Example fix

// before
let cache = EmbeddingCache::open(lmdb_path, data_path, map_size)?;

// after
if std::fs::metadata(&lmdb_path).map(|m| m.len()).unwrap_or(0) == 0 {
    anyhow::bail!("LMDB file {} is empty; run create() first", lmdb_path.display());
}
let cache = EmbeddingCache::open(lmdb_path, data_path, map_size)?;
Defensive patterns

Strategy: validation

Validate before calling

fn is_valid_lmdb(p: &Path) -> bool { std::fs::metadata(p).map(|m| m.len() > 0).unwrap_or(false) }

Try / catch

null

Prevention

When it happens

Trigger: Calling EmbeddingCache::open on an empty, freshly-created, or corrupted LMDB directory/file; pointing lmdb_path at a file created by another tool or an aborted create() run.

Common situations: Passing a wrong --lmdb-path pointing at an empty file; a previous create() crashed before writing; using open() where create() was intended.

Related errors


AI-assisted analysis of xai-org/x-algorithm@24c60942c5 (2026-08-28). Data as JSON: /api/errors/5d22e2f7274ee22c. Report an issue: GitHub.