zeroclaw-labs/zeroclaw · error

memory backend {:?} references a storage alias; construct me

Error message

memory backend {:?} references a storage alias; construct memory from the full Config so the selected alias is applied

What it means

create_memory receives only a MemoryConfig. When memory.backend contains a dot (e.g. "qdrant.prod", "postgres.main"), the suffix is a storage alias that must be looked up in the full Config's [storage.*] sections, which this function does not have. It fails fast instead of silently dropping the alias and connecting to an arbitrary or default storage.

Source

Thrown at crates/zeroclaw-memory/src/lib.rs:491

            api_key: explicit_api_key.or(inherited_api_key),
        };
    };

    ResolvedEmbeddingConfig {
        model_provider: concrete_provider,
        model,
        dimensions,
        api_key: explicit_api_key.or(provider_key).or(inherited_api_key),
    }
}

pub fn create_memory(
    config: &MemoryConfig,
    workspace_dir: &Path,
    api_key: Option<&str>,
) -> anyhow::Result<Box<dyn Memory>> {
    if config.backend.trim().contains('.') {
        anyhow::bail!(
            "memory backend {:?} references a storage alias; construct memory from the full Config so the selected alias is applied",
            config.backend
        );
    }

    create_memory_with_storage_and_routes(
        config,
        &[],
        ActiveStorage::None,
        workspace_dir,
        api_key,
        None,
    )
}

/// Construct memory from the canonical loaded configuration.
///
/// Config-aware production paths should use this entrypoint so the selected

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Call create_memory_from_config (or create_memory_with_storage_and_routes) with the full Config so the alias resolves against [storage.*].
  2. If you only have a MemoryConfig by design, strip the alias and use a plain backend name ("sqlite", "lucid", "markdown").

Example fix

// before — config.memory.backend == "qdrant.prod"
let mem = create_memory(&config.memory, workspace_dir, api_key)?;

// after
let mem = create_memory_from_config(&config, api_key)?;
Defensive patterns

Strategy: type-guard

Validate before calling

if config.memory.backend.trim().contains('.') {
    anyhow::bail!(
        "backend {:?} uses a storage alias; construct from the full Config",
        config.memory.backend
    );
}

Type guard

fn backend_needs_full_config(backend: &str) -> bool {
    backend.trim().contains('.')
}

Prevention

When it happens

Trigger: Passing a MemoryConfig whose backend is in alias (dotted) form to create_memory — commonly after extracting config.memory out of the full Config, or after constructing a MemoryConfig inline from operator docs that show dotted backend examples.

Common situations: Callers holding only the memory section of the config; tests that build MemoryConfig by hand and paste a dotted backend string; refactors that split Config and lose the storage half.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/e985ca8f882d35d0. Report an issue: GitHub.